Objective-C 继承和多态

学习Java我们知道类有三大特征,封装,继承,多态。而在Objective-C中也有继承的概念,今天就来看看Objective-C中的继承和多态。

首先,我们来看看示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Animal.h
#import <Foundation/Foundation.h>

@interface Animal : NSObject
{
int food_consumption; //食量
int count; //数量
int parturition_days; //生产周期
}

-(int)count;

-(void)setCount:(int)c;

-(int)foodConsumption;

-(void)setFoodConsumption:(int)food_c;

-(int)parturitionDays;

-(void)setParturitionDays:(int)parturition_day;

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//Animal.m
#import "Animal.h"

@implementation Animal

-(int)count{
return count;
}

-(void)setCount:(int)c{
count = c;
}

-(int)foodConsumption{
return food_consumption;
}

-(void)setFoodConsumption:(int)food_c{
food_consumption = food_c;
}

-(int)parturitionDays{
return parturition_days;
}

-(void)setParturitionDays:(int)parturition_day{
parturition_days = parturition_day;
}

@end
1
2
3
4
5
6
//Panda.h
#import "Animal.h"

@interface Panda : Animal

@end
1
2
3
4
5
6
//Panda.m
#import "Panda.h"

@implementation Panda

@end
1
2
3
4
5
6
7
8
9
10
//Tool.h
#import <Foundation/Foundation.h>
#import "Animal.h"
#import "Panda.h"

@interface Tool : NSObject

+(void) initWithAnimalDictionary:(Animal *)animal andDict:(NSDictionary *)dict;

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Tool.m
#import "Tool.h"

@implementation Tool

+(void) initWithAnimalDictionary:(Animal *)animal andDict:(NSDictionary *)dict{
NSDictionary *animalDict;
if(YES == [animal isKindOfClass:[Panda class]]){
animalDict = [dict objectForKey:@"Panda"];

}else{
NSLog(@"error class!");
}
[animal setCount:[[animalDict objectForKey:@"count"] intValue]];
[animal setFoodConsumption:[[animalDict objectForKey:@"food_consumption"] intValue]];
[animal setParturitionDays:[[animalDict objectForKey:@"parturition_days"] intValue]];
}

@end

data.plist文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fodder</key>
<dict>
<key>count_num</key>
<string>1024</string>
</dict>
<key>Panda</key>
<dict>
<key>food_consumption</key>
<string>2</string>
<key>count</key>
<string>6</string>
<key>parturition_days</key>
<string>76</string>
</dict>
</dict>
</plist>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//main.m
#import <Foundation/Foundation.h>
#import "Tool.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
Panda *panda = [[Panda alloc] init];

//读取plist
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"];
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];

[Tool initWithAnimalDictionary:panda andDict:data];

int fooder_num = 0;
int surplus = 0;
int day = 1;

NSDictionary *fooderDict = [data objectForKey:@"fodder"];
fooder_num = [[fooderDict objectForKey:@"count_num"] intValue];
surplus = fooder_num;

while(surplus > 0){
if(0 == (day % [panda parturitionDays])){
[panda setCount:([panda count] + 1)];
}
surplus = fooder_num - ([panda count] * [panda foodConsumption]);
fooder_num = surplus;

if(surplus){
NSLog(@"第 %d 天,熊猫:%d 只,饲料余量:%d 。\n", day, [panda count], surplus);
}
day++;
}
}
return 0;
}

继承

继承是类中的一个重要的特性,它的出现使得我们没必要别写重复的代码,可重用性很高。当然Objective-C中的继承和Java中是一样的,没多大区别。不仅仅Java,C++也有继承特性,但C++支持多继承,而Objective-C不支持多继承。

概念:

(1)超类(superclass),是你所继承的类。例如,Panda的超类是Animal,Animal的超类是NSObject。

(2)父类(parentclass),是超类的另一种表达方式。例如,Animal是Panda的父类。

(3)子类(subclass),是实施继承的类。例如,Panda是Animal的子类。

(4)孩子类(childclass),是子类的另一种表达方式。例如,Panda是Animal的孩子类。

继承的工作机制:

(1)方法调度

当代码发送消息时,Objective-C的方法调度程序将在当前类中搜索相应的方法。如果调度程序无法在接收消息的对象类中找到相应的方法,它就在该对象的超类中进行查找。

(2)实例变量

接下来我们看看Objective-C如何访问实例变量。创建一个新类时,其对象首先从自身的超类中继承实例变量,然后(可选)添加它们自己的实例变量。

最后,说说重写方法,制作自己全新的子类时,通常需要添加自己的方法。有时,为了在类中引入某个独特的特性,需要添加新方法。还有些时候,可能需要替换或增强由这个新类的某个超类所定义的现有方法。当遇到我们子类特有的方法时,则只需要在子类中重写该方法即可。

多态

在Objective-C中,多态就是指,父类指针可以指向子类。

1
+(void) initWithAnimalDictionary:(Animal *)animal andDict:(NSDictionary *)dict;

上例代码中的从字典中获取数据的类方法就很好地使用了多态。该方法主要是从字典中读取数据,示例中只有Panda一个子类,若是以后拥有更多的类,那么该功能的方法需要为每一个子类写一个方法,而使用多态特性,则只需根据传入的参数进行分别处理即可,减少代码冗余问题。