面向对象的多态是建立在继承上,可以说没有继承就没有多态;
多态:父类指针指向了子类的对象;
int main()
{
//假设已定义了Animal类和它的子类Dog,那么多态的代码体现就是
Animal *a = [Dog d];//父类指针指向了子类对象 }
多态的定义是比较简单的,也好理解,关键在于它的指针动态绑定,究竟调用哪个方法;
#import <Foundation/Foundation.h> //Animal类的声明
@interface Animal : NSObject
{
int _legs;
} - (void)eat;
- (void)run;
@end //Animal类的实现
@implementation Animal
- (void)eat
{
NSLog(@"动物在吃东西"); } - (void)run
{
NSLog(@"动物在跑");
} @end //子类Dog 继承 Animal
@interface Dog : Animal @end
//子类dog的实现
@implementation Dog
//方法的覆盖或叫重写
- (void)eat
{
NSLog(@"狗在吃东西");
}
@end int main()
{ Animal *a = [Dog new];//虽然表面上是一个Animal指针,但是动态绑定后,实际上它指向的是Dog类型的
[a eat];//动态绑定后,输出的时狗在吃东西,即狗的eat方法 }
这样就看到了多态的好处,当有两个方法的参数都是对象,且有共同的父类时,这两个方法可以写成一个方法,只需把参数改为父类对象就可以了
//已经定义了Dog,Cat两个类,他们都继承了Animal方法,且定义了eat方法,子类都重写了eat方法
//喂猫吃东西的方法
void catEat(Cat *c)
{
[c eat];
}
//喂狗吃东西的方法
void dogEat(Dog *d)
{
[d eat];
} /******那么这两个方法就比较冗余了,可以用一个方法代替*******/ void animalEat(Animal *a)
{
[a eat];
}
虽然多态用起来减少了代码的冗余,但是由于OC弱类型编程语言的容错能力强,局限性也很明显
1:父类对象不能调用子类的特有方法,但是真得调用了,也只是一个警告,照样能够运行起来;可以用类型转换,将父类对象转成子类的对象
语法:
Animal *aa = [Dog new];
//注意强转的格式带*号
Dog *dd = (Dog *)aa;//这里的强转也只是给编译器看得,不写,也能运行,只不过编译时一个警告;
2:一个类的指针能指向一个和本类好无关系的对象,编译只是一个警告,照样能调用其中的方法;
NSString *ns = [Dog new];
[ns eat];//只是警告,但是能运行,不建议这样写;