Thursday, November 22, 2012

Interface and Implementation

The Interface

We are all very familiar with these lines of code, right? They are found in our .h files.

@interface  ClassA:NSObject {
           dataType variable1;
}
-(returnType)method1;
@end

The purpose of interface:

The methods and the variables inside our interface are the methods and variables that can be accessed by the other classes.

The variables we put inside our curly braces are INSTANCE variables.


@interface ClassA:NSObject {
           dataType variable1;
}


A lot of people (even me) misunderstood these variables as CLASS variables.

What are Instance Variables?

"When a number of objects are created from the same class blueprint, they each have their own distinct copies of instance variables." (Source Link)
This means that every time we instantiate a class, each of these instantiations or (alloc, in our part) will have their own set of instance variables.


What are Class Variables?

"Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class." (Source Link)
This means that a particular variable will have the same value to all the other objects that instantiated that class.


Now where will you put those methods that you want to be only accessible within the class?

The Implementation

Categories and Class Extensions

Categories are very useful in adding methods to an existing class; it allows us to EXTEND the functionalities of a class without subclassing it. For example, we have Class A. Class A has method1 and method2. I also have Class B, Class B imports Class A, but I wanted to add a method in Class A without subclassing it. So I make a Category.

//Inside Implementation file of ClassB
#import "ClassA.h"
@interface ClassA(ClassA+newMethod)  <- This is a category
-(returnType)newMethod;
@end

@implementation ClassB
//implementing method in our category 'ClassA+newMethod'
-(returnType)newMethod {
}
//other methods
@end

Now, Class Extensions (or private categories) are like anonymous categories. We add methods to our class that only that method can be accessible within the class and that these methods must be implemented in our class.

//Inside Interface file of Class A
@interface  ClassA:NSObject {
           dataType variable1;
}
-(returnType)method1;
@end

//Inside Implementation file of Class A
@interface  ClassA() <- This is a class extension
{
           dataType variable2;
}
-(returnType)privateMethod;

@implementation ClassA
-(returnType)method1 {
     [self privateMethod];
}
-(returnType)privateMethod {
}
@end

With the class extension, variable2 and privateMethod can only be used inside ClassA. As we can see from the example, method1 is calling privateMethod. Class B can never see privateMethod() even if it imported and instantiated ClassA.

So, why not use @private if we only want to hide our iVars?

We already know what an instance variable is, right? @private means that our instance variables can be accessed from an instance of the class; it protects ivars from access of an instance of any other class. As for using an anonymous category, the variables can never be accessed nor seen from another class (even if it instantiated that class).
@private does not really hide our variables (example, in Class A) from any other class, example, Class B if somewhere inside Class B's codes instantiated Class A, Class B will still be able to access the private variables using the accessor methods or through the getters and setters.



1 comment: