重复的-黑马程序员--Object-C--03--继承、多态

一、继承

继承是类中的一个重要的特性,他的出现使得我们没必要别写重复的代码,可重用性很高。

参考其他文献:

成员访问类型:1、private:私有成员,不能被外部函数访问(使用),也不能被子类继承;

    2、protected:保护成员,不能被外部函数访问,可以被子类继承;

    3、public:公有成员,可以被外部函数访问,也可以被子类继承。

OC中,所有的方法(消息),都是公有的。

子类可以从父类继承方法,但是有时候父类的方法不适合子类,子类就可以写一个自己的同名方法,覆盖掉父类的同名方法,叫做重写。

举例如下:

//父类声明文件
#import 
   
   
    
    
@interface Father : NSObject

-(void)speak;

@end

//父类实现文件
#import "Father.h"
@implementation Father

-(void)speak{
    NSLog(@"I am Father!");
    return 0;

@end

   
   
子类:
//子类声明文件
#import "Father.h"

@interface Son : Father

@end

//子类实现文件
#import "Son.h"

@implementation Son

-(void)speak{
     NSLog(@"I am son!");
}

@end
子类重写父类的speak 方法,不需要重新声明。同一个方法,不同的实现,称为多态。重写是多态的一种。
当重写父类方法后子类中self与super的调用就不一样了,self调用的是子类方法,而super调用的则是父类方法。
继承的使用场合:
1、当两个类拥有相同属性和方法时,可以讲相同的东西抽取到一个父类中;
2、当A类完全拥有B类的部分属性和方法时,可以考虑B类继承A类。
继承有两缺点:
(1)当层级越来越多时,假如每个层级都有实例变量,那么最下层的子类继承的实例变量会超级多,沉重;
(2)当消息传递自子类往上时,层级越多,效率越低下。
因此出现了组合,当继承不符合逻辑时考虑用组合,继承的关系是“A is B”,组合的关系是“A has B”。
二、多态
举个例子,创建Pc父类与 LenovePc和DellPc两个子类。

Pc.h
#import 
    
    
     
     

@interface Pc : NSObject  
   
- (void) power;  
   
@end

    
    

Pc.m
#import "Pc.h"  
   
@implementation Pc  
   
- (void)power{  
    NSLog(@"PC power on!");  
}  
   
@end

LenovePc.h
#import "Pc.h"  
   
//修改父类的行为  
@interface LenovePc : Pc

- (void)power;  

@end

LenovePc.m
#import "LenovePc.h"  
   
@implementation LenovePc  
   
- (void)power{  
    NSLog(@"LenovePc power on!");  
}  
   
@end

DellPc.h
#import "Pc.h"  
   
//修改父类的打印行为  
@interface DellPc : Pc

- (void)power;  

@end

DellPc.m
#import "DellPc.h"  
   
@implementation DellPc 
   
- (void)power{  
    NSLog(@"DellPc power on!");  
}  
   
@end

在创建一个Person类用来操作Pc
Person.h
#import 
         
         
          
            
   
@interface Person : NSObject 
   
// - (void) powerWithLenove:(LenovePc *)lenovePc;
  
// - (void) powerWithDell:(DellPc *)dellPc;
   
- (void) doPower:(Pc *)pc;  
   
@end

         
         

Person.m
#import "Person.h"  
   
@implementation Person  
   
/* 
- (void) powerWithLenove:(LenovePc *)lenovePc{ 
    [lenovePc power]; 
} 
  
- (void) powerWithDell:(DellPc *)dellPc{ 
    [dellPc power]; 
} 
*/  
   
- (void) doPower:(Pc *)pc{  
    [pc power];  
}  
   
@end

主函数
main.m
#import 
           
           
            
              
   
#import "Person.h"  
#import "LenovePc.h"  
#import "DellPc.h"  
   
int main(int argc, const charchar * argv[]) {  
  
        Person *person =[Person new];  
           
        LevoerPc *lenove = [LevoerPc new];  
        DellPc *dell = [DellPc new];  
           
        //多态的定义  
        /* 
        Pc *p1 = [LevoerPc new]; 
        Pc *p2 = [DellPc new]; 
          
        [person doPower:p1]; 
        [person doPower:p2]; 
         */  
           
        int cmd;  
        do{  
            scanf("%d",&cmd);  
            if(cmd == 1){  
                // [person powerWithLenove:(LenovePc *)lenove]
                [person doPower:lenove];  
            }else if(cmd == 2){  
                // [person powerWithDell:(DellPc *)dell]
                [person doPrint:dell];  
            }  
        }while (1);  
           
    }  
    return 0;  
}

           
           

如果我们不用多态机制实现的话(Person.h中注释的代码部分),我们就要给两种Pc单独定义操作的方法,在main.m中也需要分别调用这两种方法(mai.m中的27、30行):
          
          
[person powerWithLenove:(LenovePc *)lenove]
[person powerWithDell:(DellPc *)dell]
如果我们现在又有新的惠普的Pc、华硕的Pc,我们就又需要在Person中扩充操作这些新Pc的方法,使得Peoson方法的实现臃肿累赘。
而使用多态后我们可以在Person中定义一个方法就足够了
- (void)doPower:(Pc*)pc
这个方法的参数类型是父类的类型,这就是多态,定义类型为父类类型,实际类型为调用对象的实际类型。
调用方法:
        Pc *p1 = [LevoerPc new]; 
        Pc *p2 = [DellPc new]; 
          
        [person doPower:p1]; 
        [person doPower:p2]; 
person对象调用doPower方法,传递进去的实参看起来是Pc类型,但当实参调用power方法时会动态监测调用者的真实类型,即相应的LenovePc与DellPc类型,因此会调用子类的方法。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值