1、继承
继承的好处:
创建大量的相似类的时候,可以节省工作量。
使用框架中的类,或已经写好的类,继承该类,生成一个派生类,比原类更好用。
重写(继承的另一部分)
子类可以从父类继承方法,但是有时候父类的方法不适合子类,子类就可以写一个自己的同名方法,覆盖掉父类的同名方法,叫做重写。
重写的时候,在子类的.h中不必重新声明,直接在.m中写实现就可以。
注意:NSString、NSArray、NSDictionary都是不能够继承的。
直接来看一个例子:
//------------------interface Car------------------
@interface Car : NSObject{
NSString *_brand;
NSString *_color;
}
- (void)setBrand:(NSString *)brand;
- (void)setColor:(NSString *)color;
- (void)brake;
- (void)quicken;
@end
//------------------implementation Car------------------
#import "Car.h"
@implementation Car
- (void)setBrand:(NSString *)brand{
_brand = brand;
}
- (void)setColor:(NSString *)color{
_color = color;
}
- (void)brake{
NSLog(@"刹车");
}
- (void)quicken{
NSLog(@"加速");
}
@end
//------------------interface Taxi------------------
#import "Car.h"
@interface Taxi : Car{
NSString *_company;//所属公司
}
//打印发票
- (void)printTick;
- (void)brake;
@end
//------------------implementation Taxi------------------
#import "Taxi.h"
@implementation Taxi
- (void)printTick{
[super brake];
[self brake];
NSLog(@"%@出租车打印了发票,公司为:%@,颜色为:%@",_brand,_company,_color);
}
- (void)brake{
NSLog(@"taxi brake");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Taxi *t=[[Taxi alloc]init];
[t setColor:@"blue"];
[t setBrand:@"BMW"];
[t setCompany:@"Tongda"];
[t brake];
[t printTick];
}
return 0;
}
/*
2015-07-31 20:19:04.560 test-jicheng[1388:211410] taxi brake
2015-07-31 20:19:04.560 test-jicheng[1388:211410] 刹车
2015-07-31 20:19:04.560 test-jicheng[1388:211410] taxi brake
2015-07-31 20:19:04.560 test-jicheng[1388:211410] BMW出租车打印了发票,公司为:Tongda,颜色为:blue
*/
很简单,类似于java
2、多态
多态在代码中的体现,即为多种形态,必须要有继承,没有继承就没有多态。
在使用多态是,会进行动态检测,以调用真实的对象方法。
多态在代码中的体现即父类指针指向子类对象。(*)
也来看一个例子吧(实践才出真知)
//printer&colorprinter&blackprint&people
//printer interface
@interface Printer : NSObject
-(void)print;
@end
//implementation Printer
#import "Printer.h"
@implementation Printer
-(void)print{
NSLog(@"printing...");
}
@end
//interface ColorPrinter
#import <Foundation/Foundation.h>
#import "Printer.h"
@interface ColorPrinter : Printer
-(void)print;
@end
//implementation ColorPrinter
#import "ColorPrinter.h"
@implementation ColorPrinter
-(void)print
{
NSLog(@"colorprinting....");
}
@end
//interface BlackPrinter
#import <Foundation/Foundation.h>
#import "Printer.h"
@interface BlackPrinter : Printer
-(void)print;
@end
//implementation BlackPrinter
#import "BlackPrinter.h"
@implementation BlackPrinter
-(void)print
{
NSLog(@"BKprinter...");
}
@end
//interface Person
#import <Foundation/Foundation.h>
#import "Printer.h"
@interface Person : NSObject
-(void)doprint:(Printer *)printer;
//这里看到了,这个方法的参数类型就是父类的类型,这就是多态,定义类型为父类类型,实际类型为子类类型
@end
//implementation Person
#import "Person.h"
@implementation Person
-(void)doprint:(Printer *)printer
{
[printer print];//这里调用print方法,就是传递进来的实际类型的print方法。
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person1=[[Person alloc] init];
// ColorPrinter *colprint=[[ColorPrinter alloc]init];
// BlackPrinter *bkprinter=[[BlackPrinter alloc]init];
// [person1 doprint:colprint];
// [person1 doprint:bkprinter];
Printer *printer1=[[ColorPrinter alloc]init];
Printer *printer2=[[BlackPrinter alloc]init];
//这里的printer11,printer2表面上的类型是Printer,但是实际类型是子类类型,所以会调用他们自己对应的print方法。
[person1 doprint:printer1];
[person1 doprint:printer2];
}
return 0;
}
//
//
/*多态的好处:
需要一个新的函数专门用来喂狗
Void feed(Dog *d)
{
[d eat];
}
如果这个时候也需要喂猫,那就应该重写新一个新的函数
Void feed(Cat *c)
{
[c eat];
}
而狗和猫实际上都继承自动物这个类,在这里就可以使用多态来简化代码了。
这里只需要把函数的参数写成是Animal *类型的,那么Dog和Cat类型的对象就都可以传入进来。
Void feed(Animal *a)
{
[a eat];
}
调用的时候直接改变参数就可以了。
//
//
多态的局限性:父类类型的指针变量不能直接调用子类特有的方法。
不建议的做法~
Animal *a=[[Dog alloc] init];
[a run];//在Animal类中没有run方法,这里调用了狗对象的方法。
解决方法:可以将a强制转换为Dog*类型的变量,如下:
Dog *d=(Dog *)a;//使用强制转换,这里a和d指向的是同一个狗对象
*/
多态使用总结
没有继承就没有多态
代码的体现:父类类型的指针指向子类对象
好处:如果函数方法参数中使用的是父类类型,则可以传入父类和子类对象,而不用再去定义多个函数来和相应的类进行匹配了。
局限性:父类类型的变量不能直接调用子类特有的方法,如果必须要调用,则必须强制转换为子类特有的方法。
3、描述信息的方法 通过对象自动调用
-(NSString *)description
{
NSString *message=[NSString stringWithFormat:@"%@,%@,%d",self.name,self.hobby,self.age];
return message;
}
main:
直接打印对象名即可调用description方法
4、里氏替换
Liskov于1987年提出了一个关于继承的原则“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”
——“继承必须确保超类所拥有的性质在子类中仍然成立”
-
-
-
-15.7.31
-15.8.11