OC语言 - 面向对象:多态

■ 前言

要使用多态就必须要有继承,没有继承就没有多态!多态在代码中的体现就是允许父类指针指向子类对象

OC 使用多态时会自行动态检测,以调用真实的对象方法


■ 使用多态

1. 下面是一个简单的多态

// - Animal.h :只有一个干饭的方法

1 #import <Foundation/Foundation.h>
2 
3 @interface Animal : NSObject
4 
5 - (void)eat;
6 
7 @end

// - Animal.m 

1 #import "Animal.h"
2 
3 @implementation Animal
4 
5 - (void)eat{
6 
7     NSLog(@"--%@吃东西--",self);
8 }
9 @end

// - Dog.h :继承自 Animal,但自身同样存在一个干饭的方法

#import "Animal.h"

@interface Dog : Animal
- (void)eat;
@end

// - Dog.m 

 1 #import "Dog.h"
 2 
 3 @implementation Dog
 4 
 5 - (void)eat{
 6     
 7     NSLog(@"==%@吃东西==",self);
 8 }
 9 
10 @end

// - main.m 

 1 #import <Foundation/Foundation.h>
 2 #import "Animal.h"
 3 #import "Dog.h"
 4 int main(int argc, const char * argv[]) {
 5     @autoreleasepool {
 6 
 7         Dog *dg = [[Dog alloc] init];
 8         [dg eat];  // 执行 Dog eat 方法
 9         Animal *ani = [[Animal alloc] init];
10         [ani eat]; // 执行 Animal eat 方法
11         
12         // 使用多态
13         Dog *dg01 = [[Dog alloc] init];
14         [dg01 eat]
15         Animal *ani0 = [[Dog alloc] init];// 父类指针指向子类对象
16         [ani0 eat];// 执行的是 Dog eat 方法
17         
18         // 错误使用
19         NSObject *n01 = [[Dog alloc] init];
20         NSObject *n02 = [[Animal alloc] init];
21         //[n01 eat];// 标记一
22     }
23     return 0;
24 }

2. 使用场景:比如现在要喂养 n 只不同种小动物。没使用多态时喂一只狗,那么就要给定一个函数来实现喂狗的功能

void feed(Dog *d){
  [d  eat];
}

假如你还要喂猫,于是又要新写一个函数来实现养猫的功能

void feed(Cat *c){
  [c  eat];
}

如果你还要喂猪、喂羊、喂马.......其实不论什么动物它们都继承自 Animal 这一共性。那么我们在这里就可以考虑使用多态

// 没有使用多态
void feedDog(Dog *dog){
    [dog eat];
}
// 使用了多态
void feedAnimal(Animal *ani){
    [ani eat];
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Animal *ani0 = [[Dog alloc] init];
        feedAnimal(ani0);// OC 会自动检测并执行 Dog 中的对象方法
    }
    return 0;
}

注:使用多态时父类类型的指针不能直接调用其子类独有的方法(父无子有),这就是 标记一 的原因

Animal *a=[[Dog alloc] init];
[a run];// Animal 中没有 run 方法的且只有 Dog 中存在 run 方法!程序报错

决方式:强转换下指针即可

Dog *d=(Dog *)a;// 此时的 a 和 d 指向的是同一个对象,即 Dog 实例对象

■ 多态的优缺点

1. 好处

如果函数方法参数中使用的是父类类型,则可以传入父类和子类对象,而不用再去定义多个函数来和相应的类进行匹配

不同子类对象当作父类来看,可达到屏蔽子类对象之间的差异、写出通用的代码、使程序更加灵活的目的

2. 坏处

父类类型的变量不能直接调用子类独有的方法,如果一定要调用则必须强制转换为子类后才能进行

 

posted on 2018-08-06 18:06  低头捡石頭  阅读(47)  评论(0编辑  收藏  举报

导航