1、继承与多态
先要理解实例变量的作用域:
再看继承:
即:子类的方法和属性 = 从父类继承得到的方法和属性 + 子类新增的方法和属性
例子:
// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject //其父类是NSObject
{
NSString *_name; //实例变量默认是@protected的
@private
int _age; //父类的私有实例变量
}
-(void)run; //声明run方法
@end
// Person.m
#import "Person.h"
float _salary; //定义一个父类的隐藏实例变量
@implementation Person
-(void)run{ //实现run方法
NSLog(@"person run!");
}
@end
// Student.h
#import "Person.h"
@interface Student : Person //Student类继承于Person类
-(void)printStu;
@end
// Student.m
#import "Student.h"
@implementation Student
-(void)printStu{
NSLog(@"student run!");
NSLog(@"name: %@", _name); //使用继承自父类的实例变量
}
-(void)work{
NSLog(@"s w");
}
@end
注意:
(1)父类的私有实例变量虽然能被子类继承,但不能被子类使用。如在Student类的printStu方法使用 Person类的private属性 _age则报错:
(2)父类的隐藏实例变量(在 .m文件定义的,也有的地方叫作私有变量,但觉得跟 private 的属性搞混)不能被子类继承。如如在Student类的printStu方法使用 Person类的隐藏实例变量_salary则报错:
(3)OC中的继承是单继承。即一个类至多只能有一个父类。
(4)子类可以重写父类的方法。当子类对从父类继承得到方法不满意时,可以改写之,只需要在子类的 .m文件定义一个返回类型、方法名、参数都与父类原方法相同的方法。如上例中父类Person类已经定义了run方法,Student类可以在其.m文件中添加定义:
-(void)run{ //重写run方法,覆盖父类的run方法
NSLog(@"student run!");
}
调用时,父类的对象调用父类的方法,子类的对象调用子类的方法,不引起冲突:
// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [Person