oc继承(面向对象的三大特征封装、继承、多态)
摘自:文/FoolPermi(简书作者)
原文链接:http://www.jianshu.com/p/568077956a9a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
原文链接:http://www.jianshu.com/p/568077956a9a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
@private私有成员,不能被外部函数访问,也不能被子类继承;
@protected保护成员,不能被外部函数访问,可以被子类继承;
@public共有成员,能被外部函数访问,可以被子类继承;
注意:写在实现中@implementation@end的成员变量默认是私有的
oc中,所有的成员方法(消息)都是共有的
OC的方法都是虚方法:
1.父类的指针可以指向子类的对象
2.调用方法时不看指针看对象
1.父类的指针可以指向子类的对象
2.调用方法时不看指针看对象
//父类,有一个方法jump //Father.h #import <Foundation/Foundation.h> @interface Father : NSObject - (void)jump; @end //Father.m #import "Father.h" @implementation Father -(void)jump { NSLog(@"Father can jump 1.2m."); } @end //子类,重写了jump方法 //Son.h #import"Father.h" @interface Son : Father //重写,无需声明 @end //Son.m #import "Son.h" @implementation Son -(void)jump { NSLog(@"Son can jump 1.8m."); } @end //main.m #import <Foundation/Foundation.h> #import "Father.h" #import "Son.h" int main(int argc,const char* argv[]) { @autoreleasepool{ Son* son = [[Son alloc]init]; Father* father = son;//父类的指针指向子类的对象 [father jump];//调用父类的jump还是子类的jump? //调用的仍然是子类的方法 //调用方法时不看指针,看对象 //对象的地址调用对象的方法 } return 0; }这样的方法叫做虚方法,可以描述不同事物被相同事件触发,产生不同的响应(结果)。下面写一个殴打小动物的程序。
//父类,Animal,有一个beBeaten方法,描述被打时的响应 //Animal.h #import <Foundation/Foundation.h> @interface Animal : NSObject -(void)beBeaten;//被打时的响应 @end //Animal.m #import "Animal.h" @implementation Animal -(void)beBeaten { return ;//虚方法,可以什么都不做,每个子类都会重写这个方法 } @end //Cat.h #import "Animal.h" @interface Cat : Animal @end //Cat.m #import "Cat.h" @implementation Cat -(void)beBeaten { NSLog(@"Bark and jump to high!"); } @end //Dog.h #import "Animal.h" @interface Dog : Animal @end //Dog.m #import "Dog.h" @implementation Dog -(void)beBeaten { NSLog(@"Give a hard bit!"); } @end //Frog.h #import "Animal.h" @interface Frog : Animal @end //Frog.m #import "Frog.h" @implementation Frog -(void)beBeaten { NSLog(@"Do nothing!"); } @end //Human类,有一个方法beat #import <Foundation/Fountion.h> #import "Animal.h" @interface Human : NSObject -(void)beatAnimal:(Animal*)animal;//父类的指针可以指向任意一个子类的地址,否则,殴打不同的动物,就需要创建不同的动物对象 @end //Human.m #import "Human.h" @implementation Human //只需要写一个方法,尽管动物不同,这就是父类可以指向子类的好处 -(void)beatAnimal:(Animal*)animal { NSLog(@"Human beat the %@",[animal class]); [animal beBeaten]; } @end //main.m #import <Foundation/Foundation.h> #import "Dog.h" #import "Cat.h" #import "Frog.h" #import "Human.h" int main(int argc,const char* argv[]) { @autoreleasepool{ Frog* frog = [[Frog alloc]init]; Dog* dog = [[Dog alloc]init]; Cat* cat = [[Cat alloc]init]; Human* Linda = [[Human alloc]init]; //who is Linda? [Linda beatAnimal:frog];//不同的事物被相同的事件触发,产生不同的响应 [Linda beatAnimal:cat]; [Linda beatAnimal:dog]; } return 0; }注意:
1、oc中继承不允许子类和父类拥有相同名称的成员变量,而java中是允许的
2、父类必须声明在子类的前面
3、调用某个对象方法时,优先在当前对象中找,若没有去父类中找
4、继承使类之间的耦合性增大
5、每个对象都有个isa指针,isa指针变量在NSObject中,所有类继承自NSObject,都拥有isa指针,isa指向该对象的类,类中存储着成员变量和方法,对象通过isa指针找到对应的方法调用。
多态
多态是在继承的基础上,父类指针指向子类对象
Person *p = [Man new];
同样
NSObject *n = [Man new];
注意:
1、如果函数、方法参数中使用的是父类类型,可以传入父类、子类对象
2、父类类型对象不能直接调用子类特有(不是重写的)方法,必须强制转换为子类类型变量后,才能调用
编译会报错,运行依旧,但不推荐写。(因为oc是弱类型)
如上面两句调用 [n eat]编译只会有警告,仍然能动态检查执行man的eat方法。