iOS开发-Day15-OC继承与多态

来源:互联网 发布:坚持做一件事 知乎 编辑:程序博客网 时间:2024/06/10 02:54

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");  }  @endint 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 brake2015-07-31 20:19:04.560 test-jicheng[1388:211410] 刹车2015-07-31 20:19:04.560 test-jicheng[1388:211410] taxi brake2015-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方法。}@endint 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

0 0
原创粉丝点击