Objective-C使用继承 – Objective-C开发教程

上一章Objective-C开发教程请查看:Objective-C实现双向链表、栈和队列?
继承是定义一个类继承自其它类(基类),这样我们在新的类中重用基类的代码。新定义的类称为子类或派生类,被继承的类称为基类或父类,子类可以使用父类的成员属性和成员方法。
继承一般来说是对基类的纵向扩展,假设app第一个版本基类A有5个操作功能,现在更新到第二版本如果想增加功能,删除该类还是另外重写一个A类的原有功能的类P?使用继承可以简单解决这个问题,直接新建一个类B继承自A,在B中添加新的操作功能即可,这就是继承的一个基本想法和作用。
而多态则是属于横向扩展,当你需要某一部分功能重新实现的时候,可以使用多态。
基类和子类Objective-C支持多层级继承,但是只支持一次继承一个类,OC中所有的类都是继承自NSObject,因而我们又有必要对NSObject有足够的了解,这个内容我们下一章会进行讨论。
OC继承类的语法如下:

@interface derived-class: base-class

【Objective-C使用继承 – Objective-C开发教程】derived-class是子类,而base-class是基类。在下面的例子中Person是NSObject的子类,而Employee又是Person的子类,Person是Employee的基类。
#import < Foundation/Foundation.h> @interface Person : NSObject { NSString *personName; // 实例变量,私有属性,也可以使用@property声明 NSInteger personAge; }// 自定义构造函数 - (id)initWithName:(NSString *)name andAge:(NSInteger)age; - (void)print; @end@implementation Person// 父类构造函数 - (id)initWithName:(NSString *)name andAge:(NSInteger)age { personName = name; personAge = age; return self; }- (void)print { NSLog(@"Name: %@", personName); NSLog(@"Age: %ld", personAge); }@end@interface Employee : Person { NSString *employeeEducation; }// 子类构造函数 - (id)initWithName:(NSString *)name andAge:(NSInteger)age andEducation:(NSString *)education; - (void)print; @end@implementation Employee- (id)initWithName:(NSString *)name andAge:(NSInteger)age andEducation: (NSString *)education { personName = name; personAge = age; employeeEducation = education; return self; }// 重写父类方法,覆盖父类的print - (void)print { NSLog(@"Name: %@", personName); NSLog(@"Age: %ld", personAge); NSLog(@"Education: %@", employeeEducation); }@endint main(int argc, const char * argv[]) { NSLog(@"基类对象"); Person *person = [[Person alloc]initWithName:@"AAA" andAge:5]; [person print]; NSLog(@"子类对象"); Employee *employee = [[Employee alloc]initWithName:@"BBB" andAge:5 andEducation:@"MBA"]; [employee print]; return 0; }

继承和访问控制由以上你可以看到,子类可以访问基类的所有成员,包括私有成员,但是只能在定义的时候使用,在其它地方就不能使用了,另外也不能访问父类实现文件的私有成员。
我们可以根据谁可以通过以下方式访问不同的访问类型
派生类继承所有基类方法和变量,但有以下例外
  • 在扩展的帮助下在实现文件中声明的变量不可访问。
  • 在扩展的帮助下在实现文件中声明的方法不可访问。
  • 如果继承的类实现基类中的方法,则执行派生类中的方法。
总的来说,子类是不能访问父类另外在实现文件.m中定义的任何东西。
继续下的消息传递(函数调用):先去子类找对应函数,没有找到再去父类中找。

    推荐阅读