上一章Objective-C开发教程请查看:Objective-C实现双向链表、栈和队列
继承是定义一个类继承自其它类(基类),这样我们在新的类中重用基类的代码。新定义的类称为子类或派生类,被继承的类称为基类或父类,子类可以使用父类的成员属性和成员方法。
继承一般来说是对基类的纵向扩展,假设app第一个版本基类A有5个操作功能,现在更新到第二版本如果想增加功能,删除该类还是另外重写一个A类的原有功能的类P?使用继承可以简单解决这个问题,直接新建一个类B继承自A,在B中添加新的操作功能即可,这就是继承的一个基本想法和作用。
而多态则是属于横向扩展,当你需要某一部分功能重新实现的时候,可以使用多态。
基类和子类
Objective-C支持多层级继承,但是只支持一次继承一个类,OC中所有的类都是继承自NSObject,因而我们又有必要对NSObject有足够的了解,这个内容我们下一章会进行讨论。
OC继承类的语法如下:
@interface derived-class: base-class
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);
}
@end
int 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中定义的任何东西。
继续下的消息传递(函数调用):先去子类找对应函数,没有找到再去父类中找。
评论前必须登录!
注册