Protected Methods, Private, and Public (obj c)

download demo

Protected Methods

Base.h

Note, that private attributes are accessible only by the class that declared it. No others can access it. Hence, in our Base class, it declares private attributes and freely uses it. However, in main, only the public attributes appears and can be accessed.

Base.m

Public means anyone can access these variables or methods. This includes the object themselves, as well as other objects.

When you create the Base object, and try to access the public attributes, you will see all the public members and methods we’ve declared.

public-access

Private access from other objects

You will not be able to see the private members and methods because you are not allowed access to them. Only the Base class that declared those private attributes can access them.

main.m

Derived Classes

Say we derive a child class from Base.

Child1.m

When you create a child class and derive it from a base class, you can only use the parent class’ public attributes. You cannot use its private attributes.

In other languages, we’d usually protected. Which is basically private + the ability to let child classes access your private attributes.

Protected Members (iVars)

Base.h

Base.m

Child.h

Child.m

Main

So basically, Child derives from Base. It access Base’s protected string, changes its content, and logs it. Thus we see


Child.m – This child likes to laugh.. haha!

Which is what we set in the Child class. This is how we use protected variables. However, if we were to use properties, it gets a little bit complicated.

Protected Variables (property)

First, we add properties get/set to our protectedString by doing:

Then synthesize it to generate auto-get/set methods

Finally, we implement a custom set method so that we can see how it all works. Put the custom method in your Base.m file:
Base.m

Be careful you don’t use self.protectedString because by definition, you’ll go into an infinite loop: You keep accessing your own set method.

In both Child and Base’s init, do self.protectedString. That way, we use and make our properties take into effect.

output:

—– BASE INIT start——
Base.m – iVar protectedString set

Base.m [Calling class Child] – setProtectedString <-- Base.m - protectedString was: (null) Base.m [Calling class Child] - setProtectedString -->

—– BASE INIT end ——
—– CHILD INIT start ——
Uses iVar protectedString

Base.m [Calling class Child] – setProtectedString <-- Base.m - protectedString was: Base set protectedString Base.m [Calling class Child] - setProtectedString -->

—– CHILD INIT end ——
Child.m – This child likes to laugh.. haha!

You will see that Child object in main does its init, which uses Base class’s init. Base class’s init simply uses the self.protectedString property, which calls the custom set method setProtectedString.

The custom set method sees that the iVar protectedString was null, then it gets set to “Base set protectedString”.

The Child’s init runs and using the property self.protectedString. It sees that it as a custom setProtectedString method in its Parent class, and uses that to set the iVar protectedString to a new value.

Over-riding Propert’s custom method

If your Child class wants to use its own custom method, then over-ride the Base class’s custom set method setProtectedString.

Child.m

output:


Hello, World!
—– BASE INIT start——
Base.m – iVar protectedString set

Child.m [Calling class Child] – setProtectedString <-- Child.m - protectedString was: (null) Child.m [Calling class Child] - setProtectedString -->
—– BASE INIT end ——

—– CHILD INIT start ——
Child: Uses iVar protectedString

Child.m [Calling class Child] – setProtectedString <-- Child.m - protectedString was: Base set protectedString Child.m [Calling class Child] - setProtectedString -->

—– CHILD INIT end ——
Child.m – This child likes to laugh.. haha!

Take heed that in Base’s init method, the self.protectedString accesses the custom set method in Child as shown in the output. This is because Child over-rode its parent class’s setProtectedString method.

The attribute protectedString still belongs to the Base class. The property generated its get/set in the Base class. But the Child class over-rode the set method, and thus, that’s why in Base’s init, we access the set method in Child.

Protected Methods

we use category in a dedicated header file

Base+Protected.h

Then, import the Base+Protected.h category file into your Base class. Make sure you implement the protected method.

Note that IF we have not imported Base+Protected.h, “protectedMethod” method would be a private method.

Before, we can access parent’s public. If you try to access Base’s protectedMethod, it will see it as trying to access the private of the Base class, and throw an error:

protected-cant-access

You need to #import “Base+Protected.h”, then you will be able to access the protected method which was attached to the Parent class via Category.

Thus, you just created protected access in objective c

The import of the category .h file acts as an access to private attributes mechanism. In obj c, we simply use it to give us protected-access behavior.

When you run it, you will see that the Child class calls the Base class.

Without a protected category, there would be no way for subclasses to access this method.

Keep in mind that protected attributes are really meant for child classes to use. It is still private in nature, and should not let global objects access them. They should only be accessed by its parent and anyone who is their children.

Keep in mind that accessing private and over-riding are two different things

In this section, we talk about how to have child objects access parent’s private methods via protected mechanism. However, child objects CAN accidently OVER-RIDE parent private methods:

Private methods in Objective C are semi private