zoukankan      html  css  js  c++  java
  • 黑马程序员--Objective-C之--OC面向对象的三大特征

     

    ------IOS培训期待与您交流! -------

     

    OC面向对象的三大特征是封装、继承和多态。

    OC语言也支持面向对象的三大特征,OC提供了@private、@package、@protected、@public等访问控制符来实现封装

    OC也允许子类来继承父类,并且支持多态。

    一、封装

    封装指的是將对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法对内部信息的操作和访问。

    OC的封装特性需要通过使用访问控制符来实现。

    (一)、访问控制符

    1、@private:当前类访问权限。如果类的成员变量使用@private访问控制符来限制,则这个成员变量只能在当前类的内部被访问。

    这个访问控制符用于彻底隐藏成员变量。在类的实现部分定义的成员变量相当于默认使用这种访问权限。

    2、@package:框架类访问权限。如果类的成员变量使用@package访问控制符来限制,则当前类或者同一框架中的其他类能够访问这个成员变量。

    这个访问控制符用于部分隐藏成员变量。

    3、@protected:子类访问权限。如果类的成员变量使用@protected访问控制符来限制,则当前类或者其子类能够访问这个成员变量。

    这个访问控制符用于部分隐藏成员变量。

    4、@public:公共访问权限。如果类的成员变量使用@public访问控制符来限制,则所有的类都能够访问这个成员变量。

    这个访问控制符用于彻底暴露成员变量,一般不建议这么做。

    (二)、set和get方法

    类里面的绝大部分成员变量应该使用@private进行限制,提供set和get方法访问该成员变量。

    1、set方法

    (1)作用: 提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤

    (2)命名规范:

    第一:方法名必须以set开头

    第二:set后面跟上成员变量的名称,成员变量的首字母必须大写

    第三:返回值一定是void

    第四:一定要接收一个参数,而且参数类型跟成员变量类型一致

    第五:形参的名称不能跟成员变量名一样

    2、get方法

    (1)作用:返回对象内部的成员变量

    (2)命名规范:

    第一:肯定有返回值,返回值类型肯定与成员变量类型一致

    第二:方法名跟成员变量名一样

    第三:不需要接收任何参数

    @interface Student : NSObject
    { 
        @private
        int age;
    }
    
    - (void)setAge:(int)newAge;  //set方法,用来改变age的值
    - (int)age; //get方法,用于获取age的值 @end @implementation Student // set方法的实现 - (void)setAge:(int)newAge { // 对传进来的参数进行过滤 if (newAge <= 0) { newAge = 1; } age = newAge; } - (int)age { return age; }
    @end

    二、继承

    继承是面向对象的三大特征之一,也是实现软件复用的重要手段。OC的继承具有单继承的特点,每个子类只有一个直接父类。

    (一)、继承的好处

    1、抽取重复代码

    2、建立了类之间的关系

    3、子类可以拥有父类中的所有成员变量和方法

    /********Animal的声明*******/
    @interface Animal : NSObject
    {
        int _age;
        double _weight;
    }
    
    - (void)setAge:(int)age;
    - (int)age;
    
    - (void)setWeight:(double)weight;
    - (double)weight;
    @end
    
    /********Animal的实现*******/
    @implementation Animal
    - (void)setAge:(int)age
    {
        _age = age;
    }
    - (int)age
    {
        return _age;
    }
    
    - (void)setWeight:(double)weight
    {
        _weight = weight;
    }
    - (double)weight
    {
        return _weight;
    }
    @end
    
    /********Dog*******/
    // : Dog 继承了Animal,相当于拥有了Animal里面的所有成员变量和方法
    // Animal称为Dog的父类
    // Dog称为Animal的子类
    @interface Dog : Animal
    @end
    
    @implementation Dog
    @end
    
    /********Cat*******/
    @interface Cat : Animal
    @end
    
    @implementation Cat
    @end
    
    int main()
    {
        Dog *d = [Dog new];
        
        [d setAge:10];
        
        NSLog(@"age=%d", [d age]);
        return 0;
    }

    (二)、重写父类方法

    子类重新实现父类中的某个方法,覆盖父类中的方法叫做重写。子类重写父类的方法需要注意以下几点

    第一:父类必须声明在子类的前面

    第二:子类不能拥有和父类相同的成员变量

    第三:调用某个方法时,优先去当前类中找,如果找不到,去父类中找

     

    // Person
    @interface Person : NSObject
    {
        int _age;
    }
    
    - (void)setAge:(int)age;
    - (int)age;
    
    - (void)run;
    
    + (void)test;
    
    @end
    
    @implementation Person
    
    + (void)test
    {
        NSLog(@"Person+test");
    }
    
    - (void)run
    {
        NSLog(@"person---跑");
    }
    
    - (void)setAge:(int)age
    {
        _age = age;
    }
    - (int)age
    {
        return _age;
    }
    @end
    
    // 不允许子类和父类拥有相同名称的成员变量
    // Student
    @interface Student : Person
    {
        int _no;
        // int _age;
    }
    
    + (void)test2;
    
    @end
    
    @implementation Student
    // 重写:子类重新实现父类中的某个方法,覆盖父类以前的做法 - (void)run { NSLog(@"student---跑"); } + (void)test2 { [self test]; } @end int main() { [Student test2]; // Student *s = [Student new]; // // [s run]; return 0; }

    (三)、super关键字

    如果需要在子类方法中调用父类的方法,可使用super关键字。

    super处在对象方法中,那么就会调用父类的对象方法; super处在类方法中,那么就会调用父类的类方法。

     

    // 僵尸
    @interface Zoombie : NSObject
    - (void)walk;
    
    + (void)test;
    - (void)test;
    
    @end
    
    @implementation Zoombie
    - (void)walk
    {
        NSLog(@"往前挪两步******");
    }
    
    + (void)test
    {
        NSLog(@"Zoombie+test");
    }
    
    - (void)test
    {
        NSLog(@"Zoombie-test");
    }
    @end
    
    // 跳跃僵尸
    @interface JumpZoombie : Zoombie
    + (void)haha;
    - (void)haha2;
    @end
    
    
    @implementation JumpZoombie
    
    + (void)haha
    {
        [super test];
    }
    
    - (void)haha2
    {
        [super test];
    }
    
    - (void)walk
    {
        // 跳两下
        NSLog(@"跳两下");
        
        // 走两下(直接调用父类的walk方法)
        [super walk];
        //NSLog(@"往前挪两步----");
    
    }
    @end
    
    int main()
    {
        //[JumpZoombie haha];
        JumpZoombie *jz = [JumpZoombie new];
        
        [jz haha2];
        
        return 0;
    }

    三、多态

    OC指针类型的变量有两个,一个是编译时的类型,一个是运行时的类型,编译时的类型是由声明该变量时使用的类型决定,运行时的类型由实际赋给该变量的对象决定。

    如果编译时类型和运行时类型不一致,就出现多态。

     

    // 动物
    @interface Animal : NSObject
    - (void)eat;
    @end
    
    @implementation Animal
    - (void)eat
    {
        NSLog(@"Animal-吃东西----");
    }
    @end
    
    //
    @interface Dog : Animal
    - (void)run;
    @end
    
    @implementation  Dog
    - (void)run
    {
        NSLog(@"Dog---跑起来");
    }
    - (void)eat
    {
        NSLog(@"Dog-吃东西----");
    }
    @end
    
    //
    @interface Cat : Animal
    
    @end
    
    @implementation Cat
    - (void)eat
    {
        NSLog(@"Cat-吃东西----");
    }
    @end
    
    // 这个函数是专门用来喂动画
    //void feed(Dog *d)
    //{
    //    [d eat];
    //}
    //
    //void feed2(Cat *c)
    //{
    //    [c eat];
    //}
    //
    
    // 如果参数中使用的是父类类型,可以传入父类、子类对象
    void feed(Animal *a)
    {
        [a eat];
    }
    
    int main()
    {
        // NSString *d = [Cat new];
        // [d eat];
        
        /*
        Animal *aa = [Dog new];
        // 多态的局限性:父类类型的变量 不能用来调用子类的方法
        //[aa run];
        
        // 将aa转为Dog *类型的变量
        Dog *dd = (Dog *)aa;
        
        [dd run];
        */
        
        //Dog *d = [Dog new];
        
        //[d run];
        
        /*
        Animal *aa = [Animal new];
        feed(aa);
        
        Dog *dd = [Dog new];
        feed(dd);
        
        Cat *cc = [Cat new];
        feed(cc);
         */
        
        /*
        // NSString *s = [Cat new];
        Animal *c = [Cat new];
        
        
        NSObject *n = [Dog new];
        NSObject *n2 = [Animal new];
        
        
        // 多种形态
        //Dog *d = [Dog new]; // Dog类型
        
        // 多态:父类指针指向子类对象
        Animal *a = [Dog new];
        
        // 调用方法时会检测对象的真实形象
        [a eat];
        */
        return 0;
    }
  • 相关阅读:
    mongoid和date_select的交道 小青年
    content_for对应的yield 小青年
    sunspot solr 小青年
    rails中validates及各种方法 小青年
    Rake: wrong number of arguments (3 for 2) 小青年
    nginx + nginxgridfs 安装方法 小青年
    gem install mysql2的时候出现的错误 小青年
    Rails Date Formats strftime 小青年
    redis 安装 小青年
    Uninstall all ruby gems 小青年
  • 原文地址:https://www.cnblogs.com/waterfox/p/4373471.html
Copyright © 2011-2022 走看看