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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值