zoukankan      html  css  js  c++  java
  • 6--OC--封装 继承 多态

    OC中的类的三大特性类: 继承,封装,多态

    一、 封装

    封装就是对类中的一些字段,方法进行保护,不被外界所访问到,有一种权限的控制功能,这样我们在定义类的时候,哪些字段和方法不想暴露出去,哪些字段和方法可以暴露,可以通过修饰符来完成,这就是封装,下面来看一个例子吧:

    #import <Foundation/Foundation.h>  
      
    @interface Car : NSObject{  
        //这个属性就是对外进行保密的相当于private,所以我们需要在外部访问的话,必须定义get/set方法  
        //默认的是protect的,但是我们可以使用@public设置为public属性的,那么在外部可以直接访问:person->capcity = 2.8;  
        //当然我们一般不这么使用,因为这会破坏封装性,这种用法相当于C中的结构体中权限  也就是一般不能把实例变量设置public属性
        //一共四种:@public,@protected,@private,@package,这个和Java中是相同的  
    @public  
        float _capcity; //油量属性  
    }  
      
    - (void)run:(float)t;  
      
    @end  

    这里我们可以看到,OC中也是有四种访问权限修饰符:

    @public、@protected、@private、@package

    其中默认的修饰符是@protected

    但是这里要注意的是:OC中的方法是没有修饰符的概念的,这个和Java有很大的区别,一般都是公开访问的,即public的,但是我们怎么做到让OC中的一个方法不能被外界访问呢?

    OC中是这么做的,如果想让一个方法不被外界访问的话,只需要在.m文件中实现这个方法,不要在头文件中进行定义,说白了就是:该方法有实现,没定义,这样外界在导入头文件的时候,是没有这个方法的,但是这个方法我们可以在自己的.m文件中进行使用。

    为什么要介绍这点知识呢?因为在后面我们会说到单利模式,到时候就会用到这个知识点了。

    二、继承

    继承是类中的一个重要的特性,他的出现使得我们没必要别写重复的代码,可重用性很高。当然OC中的继承和Java中是一样的,没多大区别,这里在看一个例子吧:

    首先来看一下父类:Car

    #import <Foundation/Foundation.h>  
      
      //定义两个属性和一些方法
    @interface Car : NSObject{  
        NSString *_brand;  
        NSString *_color;  
    }    
      
    - (void)setBrand:(NSString *)brand;  //父类的set方法
    - (void)setColor:(NSString *)color;  
    - (void)brake;  
    - (void)quicken;  
      
    @end  
    
    @implementation Car                //类的实现
    - (void)setBrand:(NSString *)brand{  
        _brand = brand;  
    }  
    - (void)setColor:(NSString *)color{  
        _color = color;  
    }  
    - (void)brake{  
        NSLog(@"刹车");  
    }  
    - (void)quicken{  
        NSLog(@"加速");  
    }  
    @end  
    
    // 定义一个子类 Taxi 继承的是父类Car
    @interface Taxi : Car{  
        NSString *_company;//所属公司  新增一个属性 _company
    }  
      
    //打印发票  
    - (void)printTick;  //新增一个方法 printTick
      
    @end  
    
    #import "Taxi.h"  
      
    @implementation Taxi  
      
    - (void)printTick{  
        [super brake];  // super 关键字调用父类break方法
        [self brake];   // self break 同样是调用父类方法
        NSLog(@"%@出租车打印了发票,公司为:%@,颜色为:%@",_brand,_company,_color);  
    }  
      
    @end  
    
    /*
    这里可以使用super关键字来调用父类的方法,同时这里我们也是可以用self关键字来调用,这里看到其实这两种方式调用的效果是一样的,
    当我们在子类重新实现brake方法的时候,那么这时候super关键字调用的还是父类的方法,而self调用的就是重写之后的brake方法了。
    同样,我们也是可以使用父类中的属性。
    
    */
    
    @interface Truck : Car{  
        float _maxWeight;//最大载货量  
    }  
      
    //这里就自己定义了一个brake方法,这时候就会覆盖父类中的brake方法了。覆盖父类的方法brake  
    //优先调用子类的方法  
    - (void)brake;  
      
    - (void)unload;  
      
    @end  
    
    #import "Truck.h"  
      
    @implementation Truck  
      
    - (void)brake{  
        [super brake];  
        NSLog(@"Truck类中的brake方法");  
    }  
      
    - (void)unload{  
        [super brake];//调用父类的方法  
        [self brake];//也是可以的  这里就可以看到,我们会在brake方法中调用一下父类的brake方法,然后在实现我们自己的逻辑代码。
        NSLog(@"%@的卡车卸货了,载货量:%.2f,汽车的颜色:%@",_brand,_maxWeight,_color);  
    }  
      
    @end  
    

    三、多态

    多 态对于面向对象思想来说,个人感觉是真的很重要,他对以后的编写代码的优雅方式也是起到很重要的作用,其实现在很多设计模式中大部分都是用到了多态的特 性,Java中的多态特性用起来很是方便的,但是C++中就很难用了,其实多态说白了就是:定义类型和实际类型,一般是基于接口的形式实现的.

    书面意思就是: 来自不同类的对象可以定义共享相同名称的方法  

    多态:相同的名称 不同的类  (多种形态)

    #import <Foundation/Foundation.h>
    
    @interface Animal :NSObject  //定义一个Animal类
    - (void)eat;
    
    @end
    
    @implementation Animal  // 实现Animal类
    
    -(void)eat
    {
    	NSLog(@"Animal 吃东西----");	
    }
    @end 
    
    @interface Dog:Animal  //定义一个Dog 类 继承Animal
    - (void)eat;
    
    @end
    
    @implementation Dog  // 实现Dog 类
    - (void)eat
    {
    	NSLog(@"Dog 吃东西----");	
    	
    }
    @end  
    
    int main()
    {
    	//多种形态
    	Dog *a = [Dog new];  //dog 类型
    	[a eat];  // 调用的是Dog类方法
    	
    	//多态:父类指针指向子类对象
    	Animal *a1 = [Dog new]; // 这里可以发现将Dog 对象给到了Animal类而没有给到Dog 类
    	[a1 eat];
    
        return 0;	
    	
    }
    
    /*
    类的多态:
    1>必须有继承才可以使用多态
    
    */
    
    
    
    #import <Foundation/Foundation.h>
    
    @interface Animal :NSObject  //定义一个Animal类
    - (void)eat;
    @end
    
    @implementation Animal  // 实现Animal类
    -(void)eat
    {
    	NSLog(@"Animal 吃东西----");	
    }
    @end 
    
    @interface Dog:Animal  //定义一个Dog 类 继承Animal
    - (void)eat;
    @end
    
    @implementation Dog  // 实现Dog 类
    - (void)eat
    {
    	NSLog(@"Dog 吃东西----");	
    }
    @end  
    
    @interface Cat :Animal  //定义Cat 类
    -(void)eat
    
    @end
    
    @implementation Cat//实现cat 类
    -(void)eat
    {
    	NSLog(@"Cat 吃东西----");	
    }
    
    @end
    
    -(void)eat(Animal *a)
    {
    	
    	[a eat];
    	
    }
    int main()
    {
    	
    	
    	//Cat *c =[Dog new]; //这个在编译器中是不报错的只会提醒,因为把Dog 划到Cat类不符合逻辑 因为OC是弱语法
    	//Cat *c = [Animal new];  // Animal 不是Cat 所以也会出现警告
    	
    //正常的写法就可以这样写:
    
    /*
    Animal *c = [Cat new];
    NSObject *C = [Cat new]; 
    NSObject *D = [Dog new];
    */
    
    //多态的好处 避免重复代码来实现喂猫 喂狗 讲子类对象直接传递到父类指针即可
    Animal *a [Animal new];
    feed (a);
    
    Dog *d = [Dog new];
    feed (d);
    
    Cat *c = [Cat new];
    feed(c);
    
    	
    	//多种形态
    	Dog *a = [Dog new];  //dog 类型
    	[a eat];  // 调用的是Dog类方法
    	
    	//多态:父类指针指向子类对象
    	Animal *a1 = [Dog new]; // 这里可以发现将Dog 对象给到了Animal类而没有给到Dog 类
    	
    	//调用方法是会检测对象的真实形象
    	[a1 eat];  // 输出的是dog方法 
    
        return 0;	
    	
    }
    
  • 相关阅读:
    梦断代码阅读笔记一
    进度一
    LOJ#6031. 「雅礼集训 2017 Day1」字符串
    cf700E. Cool Slogans
    BZOJ1014: [JSOI2008]火星人prefix
    BZOJ2716: [Violet 3]天使玩偶
    cf1080F. Katya and Segments Sets
    BZOJ1354: [Baltic2005]Bus Trip
    灭绝树题集
    How Many Substrings?
  • 原文地址:https://www.cnblogs.com/stephenmc/p/5242861.html
Copyright © 2011-2022 走看看