标签:
前言:
oc中的指针类型变量有两个:一个是编译时类型,一个是运行时类型,编译时类型由声明该变量是使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就有可能出现多态。
正文:
新建一个CHPerson类
1 @interface CHPerson : NSObject
2 -(void)eat;
3 -(void)play;
4 @end
5 ---------------------------------------------------------
6 #import "CHPerson.h"
7
8 @implementation CHPerson
9 -(void)eat{
10 NSLog(@"----父类的吃");
11 }
12 -(void)play{
13 NSLog(@"-----父类的玩");
14 }
15 @end
新建一个继承于CHPerson的CHchina类
1 #import "CHPerson.h"
2
3 @interface CHChina : CHPerson
4 -(void)playgame;
5 @end
6
7 ----------------------------------------------------
8
9 #import "CHChina.h"
10
11 @implementation CHChina
12 -(void)eat{
13 NSLog(@"=======子类的吃");
14 }
15 -(void)playgame{
16 NSLog(@"玩游戏");
17 }
18 @end
调用方法:
1 #import "ViewController.h"
2 #import "CHChina.h"
3 @interface ViewController ()
4
5 @end
6
7 @implementation ViewController
8
9 - (void)viewDidLoad {
10 [super viewDidLoad];
11 // 下面编译时类型和运行时类型完全一样,因此不存在多态
12 CHPerson *person = [[CHPerson alloc]init];
13 [person eat];
14
15 // 下面编译时类型和运行时类型完全一样,因此不存在多态
16 CHChina *china = [[CHChina alloc]init];
17 [china eat];
18
19 // 下面编译时类型和运行时类型不一样,因此发生多态
20 CHPerson *perch = [[CHChina alloc]init];
21 // 调用从父类继承的play方法
22 [perch play];
23 // 调用子类重写eat方法
24 [perch eat];
25
26 // 因为perch的编译时类型是CHPerson,但CHPerson没有playgame方法,所以编译时会报错
27 // [perch playgame];
28 // 但可以将任何类型的指针变量赋值给id类型的变量
29 id allperch = perch;//下面会解释为何这样做?
30 [allperch playgame];
31
32 }
结果:
1 2015-10-01 17:54:03.705 多态[86274:361586] ----父类的吃 13行代码结果
2 2015-10-01 17:54:03.705 多态[86274:361586] =======子类的吃
3 2015-10-01 17:54:03.706 多态[86274:361586] -----父类的玩
4 2015-10-01 17:54:03.706 多态[86274:361586] =======子类的吃 24行代码结果
5 2015-10-01 17:54:03.706 多态[86274:361586] 玩游戏
补充(id):oc中提供了一个id类型,这个id类型可以代表所有对象的类型。就是说,任意类型的对象都可以赋值给id类型变量。
当通过id类型变量来调用方法时,oc将会执行动态绑定,动态绑定,是指oc将会跟踪对象所属类,它会在运行时判断该对象所属类,并在运行时确定需要动态调用的方法,而不是在编译时确定要调用的方法。如上面,程序会在运行时动态检测该变量所指的对象的实际类型为CHChina,所以会动态绑定到执行CHChina的eat方法。
标签:
原文地址:http://www.cnblogs.com/chenhongios/p/4851487.html