学习Java我们知道类有三大特征,封装,继承,多态.而在Objective-C中也有继承的概念,今天就来看看Objective-C中的继承和多态.
首先,我们来看看示例代码:
//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
//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
//Panda.h #import "Animal.h" @interface Panda : Animal @end
//Panda.m #import "Panda.h" @implementation Panda @end
//Tool.h #import <Foundation/Foundation.h> #import "Animal.h" #import "Panda.h" @interface Tool : NSObject +(void) initWithAnimalDictionary:(Animal *)animal andDict:(NSDictionary *)dict; @end
//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文件
<?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>
//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中,多态就是指,父类指针可以指向子类.
+(void) initWithAnimalDictionary:(Animal *)animal andDict:(NSDictionary *)dict;
上例代码中的从字典中获取数据的类方法就很好地使用了多态.该方法主要是从字典中读取数据,示例中只有Panda一个子类,若是以后拥有更多的类,那么该功能的方法需要为每一个子类写一个方法,而使用多态特性,则只需根据传入的参数进行分别处理即可,减少代码冗余问题.
以上,是学习Objective-C时对继承和多态的理解.