One of the most important concepts in object-oriented programming is that of inheritance. Inheritance allows us to define a class in terms of another class which makes it easier to create and maintain an application. This also provides an opportunity to reuse the code functionality and fast implementation time.
As with most programming concepts the subject of inheritance in Objective-C is perhaps best illustrated with an example. In the An Overview of Objective-C Object Oriented Programming we created a class called BankAccount designed to hold a bank account number and corresponding current balance
When creating a class, instead of writing completely new data members and member functions, the programmer can designate that the new class should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class.
The idea of inheritance implements the is a relationship. For example, mammal IS-A animal, dog IS-A mammal, hence dog IS-A animal as well and so on.
Objective-C allows only Multiple inheritance, it can have only one base class but allows multilevel inheritance. All classes in Objective-C is derived from the superclass NSObject.
@interface derived-class: base-class
Terminology
A root class is at the top of the inheritance hierarchy. Almost all Cocoa Touch and Foundation classes inherit from NSObject. Incidentally, NSObject is also an abstract class, so called because it’s not designed to be actually used—rarely will you ever use an NSObject; you’ll usually create and use subclasses. An abstract class therefore is one that is created for the purposes of subclassing.
A class that inherits from another is known as a child or subclass of its or superclass.
Every subclass inherits certain properties of its superclass; exactly what is inherited can be controlled. By default, every class has access to all the instance variables of its superclass, and they work exactly as if you had defined those ivars in the subclass itself. In addition, a subclass will inherit any public methods that its superclass defines. As an example (kept in one file for brevity):
@interface Superclass : NSObject {
int v;
}
- (void)initV;
@end
@implementation Superclass
- (void)initV {
v = 20;
}
@end
@interface Subclass : Superclass {
int w;
}
- (void)displayVars;
@end
@implementation Subclass
- (void)initW {
w = 50;
}
- (void)displayVars {
NSLog(@"v is %d, w is %d", v, w);
}
@end
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Subclass *sub = [[Subclass alloc] init];
[sub initV]; // Inherited method & ivar
[sub initW]; // Own method & ivar
[sub displayVars]; // Inherited method [sub release];
[pool drain];
return 0;
}
Output:
v is 20, w is 50
Inheritance chain:
[As you can see, we created an instance of an object of type Subclass. We then used it as any other class. Notice, however, that we called initV on the Subclass, and accessed the v ivar, neither of which were declared in Subclass. This is because these were already present in Superclass, and Subclass inherited them. The output proves that Subclass was able to access the inherited variables.]
Remember that a method is simply a declaration of what a class can do; when it is invoked at runtime, it is chosen out of that “list”. The procedure is very simple. The runtime environment searches for an explicit declaration of that method in the class of the object that you sent the message to (in the above example, the search for displayVars begins with the Subclass class. If it is found in that class, it invokes that method (in other words, it invokes the version closest to that class in the inheritance chain). If it isn’t found, it looks for the method in the superclass; if it’s found, it invokes that version; if not, the search continues, until either the method is found, or it isn’t. In the latter case, you get a compiler warning, that the class may not respond to the specific method. When your code tries to call this method during execution, your program will likely crash.
Access Control and Inheritance:
A derived class can access all the private members of its base class if it's defined in the interface class, but it cannot access private members that are defined in the implementation file.
We can summarize the different access types according to who can access them
in the following way:
A derived class inherits all base class methods and variables with the following exceptions:
· Variables declared in implementation file with the help of extensions is not accessible.
· Methods declared in implementation file with the help of extensions is not accessible.
· In case the inherited class implements the method in base class, then the method in derived class is executed.
Leave Comment