zoukankan      html  css  js  c++  java
  • IOS开发学习笔记010-面向对象的三大特性

    面向对象的三大特性

      1、封装

      2、继承

      3、多态

    一、封装

    将类内部的属性保护起来,在外部不能直接访问,那么如果需要访问怎么办呢?

    OC提供了set方法来对成员变量进行访问

    set方法

    1、作用:提供一个方法给外界设置age属性的值

    2、命名规范

       方法名必须是set开头

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

       返回值一定是void

       一定要接收一个参数,并且和成员变量类型一致

       形参名不能和成员变量名一样

     声明

    - (void)setAge:(int)newAge;//声明

    实现

    1 - (void)setAge:(int)newAge//set方法实现
    2 {
    3     if(newAge <= 0)//如果小于0岁就赋值为1
    4     {
    5         newAge = 1;
    6     }
    7     age = newAge;//设置年龄
    8 }

    使用

    1  Student *p = [Student new];//新建对象
    2  [p setAge:20];//设置属性
    3  [p study];//调用方法

     get方法

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

     2、命名规范:

        肯定有返回值,返回类型和成员变量一致

        方法名和成员变量名一样

        不需要接收参数

    声明

    - (int)age;//

    实现

    1 - (int)age//
    2 {
    3     return age;
    4 }

    使用

    1  NSLog(@"%d岁的学生在学习!",[p age]);

    成员变量的使用

    命名规范:

      成员变量都以下划线 _ 开头

      可以跟get方法的名称区分开

      可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量

     1 @interface Student : NSObject
     2 {
     3     //@public
     4     //成员变量
     5     //让成员变量和get方法区分开,成员变量都要加_
     6     int _no;
     7     int _age;
     8     Sex _sex;
     9 }
    10 
    11 @end

    练习1

     1 #import <Foundation/Foundation.h>
     2 
     3 //成绩类
     4 /*
     5     C成绩(读写)
     6     OC成绩(读写)
     7     平均分(只读)
     8     总分(只读)
     9  */
    10 //类的声明
    11 @interface Score : NSObject
    12 {
    13     int _cScore;//c成绩
    14     int _ocScore;//oc成绩
    15     
    16     int _totalScore;//总分
    17     int _averageScore;//平均分
    18 }
    19 
    20 //方法声明
    21 //set
    22 - (void)setCScore:(int)newCScore;
    23 - (void)setOcScore:(int)newOcScore;
    24 
    25 //get
    26 - (int)cScore;
    27 - (int)ocScore;
    28 - (int)totalScore;
    29 - (int)averageScore;
    30 
    31 @end
    32 
    33 
    34 
    35 //类的实现
    36 @implementation Score
    37 //方法实现
    38 - (void)setCScore:(int)newCScore
    39 {
    40     _cScore = newCScore;
    41     //计算总分和平均分
    42     _totalScore = _cScore + _ocScore;
    43     _averageScore = _totalScore/2;
    44 }
    45 - (void)setOcScore:(int)newOcScore
    46 {
    47     _ocScore = newOcScore;
    48     //计算总分和平均分
    49     _totalScore = _cScore + _ocScore;
    50     _averageScore = _totalScore/2;
    51 }
    52 
    53 - (int)cScore
    54 {
    55     return _cScore;
    56 }
    57 - (int)ocScore
    58 {
    59     return _ocScore;
    60 }
    61 - (int)totalScore
    62 {
    63     return _totalScore;
    64 }
    65 - (int)averageScore
    66 {
    67     return _averageScore;
    68 }
    69 @end
    70 
    71 
    72 int main()
    73 {
    74     Score *p = [Score new];//新建对象
    75     [p setCScore:100];//set方法
    76     [p setOcScore:90];//set方法
    77     
    78     NSLog(@"总分:%d",[p totalScore]);
    79     
    80     NSLog(@"平均分:%d",[p averageScore]);
    81     
    82     return 0;
    83 }

    OC弱语法

    如果调用不存在的方法,那么在编译和链接时都不会报错,最多有一个警告。只有在运行时才回出错。

    unrecognized selector sent to instance 0x0000034034C0

    给对象发送的消息不能识别

    OC只有在运行过程中才会检测对象有没有实现相应的方法。

    类方法

    1、以+开头

    2、通过类名调用的方法。

    3、类方法不能访问成员变量

    4、类方法和对象方法可以重名

    5、使用场合:当不需要访问成员变量时尽量用类方法

    声明

    + (void)printClassName;//

    实现

    1 + (void)printClassName//
    2 {
    3     NSLog(@"class name is Person");
    4 }

    使用

     [Person printClassName];//类方法的调用,直接使用类名

    工具类

    没有成员变量的类,里面的方法全是类方法。

    示例

     1 #import <Foundation/Foundation.h>
     2 /*
     3 工具类
     4     没有成员变量
     5     所有方法全是类方法
     6  */
     7 //类声明
     8 @interface JiSuanQi : NSObject
     9 
    10 + (void)printClassName;//类方法
    11 
    12 + (int)sumOfSum1:(int)sum1 andSum2:(int)sum2;//类方法
    13 
    14 @end
    15 //类的实现
    16 @implementation JiSuanQi
    17 + (void)printClassName
    18 {
    19     NSLog(@"class name is JiSuanQi");
    20     
    21 }
    22 + (int)sumOfSum1:(int)sum1 andSum2:(int)sum2
    23 {
    24     return sum1 + sum2;
    25 }
    26 
    27 @end
    28 
    29 int main()
    30 {
    31  
    32     [JiSuanQi printClassName];//类方法的调用,直接使用类名
    33     int res = [JiSuanQi sumOfSum1:10 andSum2:20];
    34     NSLog(@"%d",res);
    35     return 0;
    36 }

    self关键字

    谁调用,self代表谁。

    如果用对象调用,就代表对象,如果是类调用,就代表类。

    成员变量和局部变量同名

      当成员变量和局部变量同名时,采取就近原则,访问的是局部变量

      用self访问成员变量,区分同名的局部变量

    self出现的位置:

      所有的OC方法中(对象方法类方法),不能出现在函数

    作用方式:

      使用 "self->成员变量名" 访问当前方法调用的成员变量

      使用 "[self 方法名];" 来调用方法(对象方法类方法)

    1 - (void)setAge:(int)newAge
    2 {
    3     _age = newAge;
    4 
    5     int _age = 10;//局部变量与成员变量同名时,如果需要使用成员变量,则需要使用self关键字
    6     NSLog(@"age is %d",self->_age);//self 是一个指指针,指向调用的对象
    7 }

     小练习

       设计Car类,一个对象方法跟其他车子比较车速,返回速度差,一个类方法比较两辆车的车速,返回速度差

     1 #import <Foundation/Foundation.h>
     2 
     3 //类的声明
     4 @interface Car : NSObject
     5 {
     6     int _speed;//速度
     7 }
     8 - (void)setSpeed:(int)newSpeed;
     9 - (int)speed;
    10 //对象方法
    11 /*
    12 作用:比较两辆车的速度大小,返回差值
    13 方法名:differenceSpeedWithOtherCar:
    14 参数:(Car *)otherCar
    15 返回值:int
    16  */
    17 - (int)differenceSpeedWithOtherCar:(Car *)otherCar;
    18 
    19 //类方法
    20 /*
    21  作用:比较两辆车的速度大小,返回差值
    22  方法名:differenceSpeedWithCar1: :
    23  参数:(Car *)Car1 (Car *)Car2
    24  返回值:int
    25  */
    26 + (int)differenceSpeedWithCar1:(Car *)Car1 andCar2:(Car *)Car2;
    27 @end
    28 
    29 //类的实现
    30 @implementation Car
    31 //对象方法的实现
    32 - (void)setSpeed:(int)newSpeed
    33 {
    34     _speed = newSpeed;
    35 }
    36 
    37 - (int)speed
    38 {
    39     return _speed;
    40 }
    41 
    42 //对象方法
    43 - (int)differenceSpeedWithOtherCar:(Car *)otherCar
    44 {
    45     return [self speed] - [otherCar speed];//self指向调用者也就是本对象
    46 }
    47 
    48 //类方法
    49 
    50 + (int)differenceSpeedWithCar1:(Car *)Car1 andCar2:(Car *)Car2;
    51 {
    52     return [Car1 speed] - [Car2 speed];//通过类调用的话,只能传进来两个参数,因为默认成员变量是0,没有任何实际意义。
    53 }
    54 
    55 @end
    56 
    57 int main()
    58 {
    59     Car *p1 = [Car new];
    60     [p1 setSpeed:300];
    61     
    62     Car *p2 = [Car new];
    63     [p2 setSpeed:200];
    64     
    65     Car *p3 = [Car new];
    66     [p3 setSpeed:90];
    67     
    68     int  res = [p1 differenceSpeedWithOtherCar:p2];//使用对象调用方法
    69     NSLog(@"%d",res);
    70     
    71     res = [Car differenceSpeedWithCar1:p1 andCar2:p3];//使用类调用方法
    72     NSLog(@"%d",res);
    73     return 0;
    74 }

    二、继承

     子类从父类继承一些公共属性和方法。

     不允许子类和父类拥有同名的成员变量。

     方法可以和父类的方法同名(重写),调用过程是先找子类的,再找父类的。

     继承的使用场合

      1、当两个类拥有相同的属性和方法时,可以将相同的东西抽象到一个类中

      2、当类a中含有类B所需的全部或部分属性和方法时,可以让B继承A

    继承与组合区别

      继承:A 是 B;

      组合:A 拥有B;

    示例

     1 #import <Foundation/Foundation.h>
     2 
     3 //Animal类的声明
     4 @interface Animal : NSObject
     5 {
     6     int _age;//年龄
     7     double _weight;//体重
     8 }
     9 //对象方法
    10 - (void)setAge:(int)newAge;
    11 - (int)age;
    12 
    13 - (void)setWeight:(int)newWeight;
    14 - (double)weight;
    15 
    16 - (void)run;
    17 @end
    18 
    19 
    20 //Animal类的实现
    21 @implementation Animal
    22 //方法实现
    23 - (void)setAge:(int)newAge
    24 {
    25     _age = newAge;
    26 }
    27 - (int)age
    28 {
    29     return _age;
    30 }
    31 
    32 - (void)setWeight:(int)newWeight
    33 {
    34     _weight = newWeight;
    35 }
    36 - (double)weight
    37 {
    38     return _weight;
    39 }
    40 
    41 - (void)run
    42 {
    43     NSLog(@"动物在奔跑!");
    44 }
    45 
    46 @end
    47 
    48 
    49 
    50 
    51 
    52 //Dog类的声明
    53 @interface Dog : Animal
    54 {
    55     //int _age;//子类不能和父类的成员变量重名
    56     int gouPai;//狗牌
    57 }
    58 //对象方法
    59 - (void)run;//重写父类的方法
    60 @end
    61 
    62 
    63 //Dog类的实现
    64 @implementation Dog
    65 //方法实现
    66 - (void)run
    67 {
    68     NSLog(@"Dog在奔跑!");
    69 }
    70 
    71 @end
    72 
    73 //Cat类的声明
    74 @interface Cat : Animal
    75 {
    76     
    77 }
    78 //对象方法
    79 
    80 @end
    81 
    82 
    83 //Cat类的实现
    84 @implementation Cat
    85 //方法实现
    86 
    87 
    88 @end
    89 
    90 int main()
    91 {
    92     Dog *d = [Dog new];
    93     [d setAge:4];
    94     [d run];//子类的run会覆盖父类的run方法
    95     NSLog(@"%d",[d age]);
    96     
    97     return 0;
    98 }

    super关键字

    如果在子类中想访问父类的方法(对象方法和类方法都可以),可以使用关键字super进行调用 ;  

    [super walk];//具体是对象方法还是类方法取决于调用时所处于的环境。

    使用场景:子类使用父类的方法时想保留父类的一些操作

    1 //方法实现
    2 - (void)run
    3 {
    4     NSLog(@"Dog在奔跑!");
    5     
    6     [super run];//super 关键字,调用父类的方法
    7 }

    三、多态

      父类指针指向子类对象:多态

     1、没有继承就没有多态

    2、父指针指向子类对象

    3、优点:函数/方法传入父指针,则在调用时可以传入子类指针和父类指针

    4、缺点:父类类型的变量,不能直接调用子类特有的方法

    代码示例

      1 #import <Foundation/Foundation.h>
      2 /*
      3 多态
      4  
      5  */
      6 
      7 
      8 //Animal类的声明
      9 @interface Animal : NSObject
     10 {
     11    // int _age;//年龄
     12     //double _weight;//体重
     13 }
     14 //对象方法
     15 
     16 - (void)eat;
     17 @end
     18 
     19 
     20 //Animal类的实现
     21 @implementation Animal
     22 //方法实现
     23 - (void)eat
     24 {
     25     NSLog(@"吃吃吃!");
     26 }
     27 
     28 @end
     29 
     30 
     31 
     32 
     33 
     34 //Dog类的声明
     35 @interface Dog : Animal
     36 {
     37     //int _age;//子类不能和父类的成员变量重名
     38     //int gouPai;//狗牌
     39 }
     40 //对象方法
     41 - (void)eat;//重写父类的方法
     42 @end
     43 
     44 
     45 //Dog类的实现
     46 @implementation Dog
     47 //方法实现
     48 - (void)eat
     49 {
     50     NSLog(@"Dog在吃吃吃!");
     51     
     52    // [super eat];//super 关键字,调用父类的方法
     53 }
     54 
     55 @end
     56 
     57 
     58 //Cat类的声明
     59 @interface Cat : Animal
     60 {
     61     //int _age;//子类不能和父类的成员变量重名
     62     //int gouPai;//狗牌
     63 }
     64 //对象方法
     65 - (void)eat;//重写父类的方法
     66 - (void)run;
     67 @end
     68 
     69 
     70 //Dog类的实现
     71 @implementation Cat
     72 //方法实现
     73 - (void)eat
     74 {
     75     NSLog(@"Cat在吃吃吃!");
     76     
     77     // [super eat];//super 关键字,调用父类的方法
     78 }
     79 - (void)run
     80 {
     81       NSLog(@"Cat在跑!");
     82 }
     83 @end
     84 
     85 
     86 int main()
     87 {
     88     //Dog *d = [Dog new];
     89 
     90     //父类指针指向子类对象:多态
     91     Animal *a = [Dog new];
     92     //[a run];//父类指针调用子类的特有方法,会有警告
     93 
     94     
     95     Dog *d = (Dog *)a;//可以强制转换,调用子类特有的方法
     96     [d eat];
     97     
     98     
     99     
    100     return 0;
    101 }
  • 相关阅读:
    [SCOI2010] 生成字符串
    [NOIp2010] 机器翻译
    [CF792E] Colored Balls
    JS6-函数1
    JS6-字符串
    JS6-函数
    JS
    Bootstrap
    JQuery 自己的理解
    JQuery
  • 原文地址:https://www.cnblogs.com/songliquan/p/4431943.html
Copyright © 2011-2022 走看看