------ android培训、java培训、期待与您交流! ----------
OC基础—三大特性之多态
三大特性之多态:多种形态的意思(对象),多态是有条件的:必须有继承,没有继承就没有多态。
基本使用:
#import <Foundation/Foundation.h>
// ***************Animal类****************
@interface Animal : NSObject
- (void)eat;
@end
@implementation Animal
- (void)eat
{
NSLog(@"Animal吃东西——————");
}
@end
//**************Dog类****************
@interface Dog : Animal
@end
@implementation Dog
- (void)eat
{
NSLog(@"Dog吃东西——————");
}
@end
int main( )
{
NSObject *n = [Animal new]; // 这也是多态
// 多种形态
Dog *d = [Dog new]; // Dog类型
// 多态:父类指针指向子类对象
Animal *a = [Dog new];
// 调用方法时会检测对象的真实类型
[a eat]; // 调用Dog中的eat
return 0;
}
我们知道了多态的条件就是继承,没有继承就没有多态。
Animal *a = [Dog new];这就是多态:父类指针指向子类对象。
在调用方法时会自动检测对象的真是对象,之后在真实对象中需找相应的方法。
使用注意:
Dog *d = [Animal new]; 这是将子类指针指向父类,这样写是不对的。可以说Animal是一个Dog么?这是错误写法,并不是多态。但是你这样写了,编译器并不会报错,应为OC的弱语法缘故,哪怕是NSString *str = [Animal new];这样写,编译器也不会报错,但是我们要知道,这样写是不对的。
多态的好处:
给上面的代码添加一个feed函数
void feed(Animal *a)
{
[a eat];
}
int main( )
{
Animal *aa = [Animal new];
feed(aa);
Dog *dd = [Dog new];
feed(dd);
return 0;
}
这样就可以看出多态的好处:上面的feed函数,如果参数中使用的是父类类型,可以传入父类、子类对象
局限性:
在上面的代码中Dog类中增加一个方法
- (void)run
{
NSLog(@"Dog跑起来了");
}
main函数中调用
Animal *animal = [Dog new];
[animal run];
编译器是比较笨的,在animal调用run函数的时候,看到Animal *animal就会认为animal真的是Animal类的,Animal中没有run方法,这时编译器会发出一个警告(OC弱语法),但是还是可以运行的。但是这是规范问题 ,不能这样调用。
父类类型的变量 不能 用来调用子类方法(可以成功,但是不规范,不建议使用)
强制转化可以:
Animal *animal = [Dog new];
// 将animal转换成Dog *类型
Dog *dd = (Dog *)animal;
[dd run];
这样就可以了。