OC面向对象多态笔记

面向对象的多态是建立在继承上,可以说没有继承就没有多态;

多态:父类指针指向了子类的对象;

1 int main()
2 {
3       //假设已定义了Animal类和它的子类Dog,那么多态的代码体现就是
4         Animal *a = [Dog d];//父类指针指向了子类对象
5         
6 }

多态的定义是比较简单的,也好理解,关键在于它的指针动态绑定,究竟调用哪个方法;

 1 #import <Foundation/Foundation.h>
 2 
 3 //Animal类的声明
 4 @interface Animal : NSObject
 5 {
 6     int _legs;
 7 }
 8 
 9 - (void)eat;
10 - (void)run;
11 @end
12 
13 //Animal类的实现
14 @implementation Animal
15 - (void)eat
16 {
17     NSLog(@"动物在吃东西");
18     
19 }
20 
21 - (void)run
22 {
23     NSLog(@"动物在跑");
24 }
25 
26 @end
27 
28 //子类Dog 继承 Animal
29 @interface Dog : Animal
30 
31 @end
33 //子类dog的实现
34 @implementation Dog
35 //方法的覆盖或叫重写
36 - (void)eat
37 {
38     NSLog(@"狗在吃东西"); 
40 }
41 @end
42 
43 int main()
44 {
45     
46     Animal *a = [Dog new];//虽然表面上是一个Animal指针,但是动态绑定后,实际上它指向的是Dog类型的
47     [a eat];//动态绑定后,输出的时狗在吃东西,即狗的eat方法
48     
49 }

这样就看到了多态的好处,当有两个方法的参数都是对象,且有共同的父类时,这两个方法可以写成一个方法,只需把参数改为父类对象就可以了

//已经定义了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];//只是警告,但是能运行,不建议这样写;
原文地址:https://www.cnblogs.com/cxbblog/p/3710498.html