zoukankan      html  css  js  c++  java
  • 07-继承使用过程中的注意点(含代码)

    1、父类必须写在子类之前

     1 #import <Foundation/Foundation.h>
     2 @interface Student : Person
     3 @end
     4 
     5 @implementation Student
     6 @end
     7 
     8 @interface Person : NSObject
     9 @end
    10 
    11 @implementation Person
    12 @end
    13 
    14 int main()
    15 {
    16     return 0;
    17 }

    由于编译器读取代码是从上到下逐行读取的,当读到第2行的时候,会找不到Person类,于是报错

    正确写法如下:

     1 #import <Foundation/Foundation.h>
     2 @interface Person : NSObject
     3 @end
     4 
     5 @implementation Person
     6 @end
     7 
     8 @interface Student : Person
     9 @end
    10 
    11 @implementation Student
    12 @end
    13 
    14 int main()
    15 {
    16     return 0;
    17 }

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

      1>父类中已有的成员变量,子类中不能重复声明。即不允许子类和父类拥有相同名称的成员变量

    下面的代码是错误的:

     1 #import <Foundation/Foundation.h>
     2 @interface Person : NSObject
     3 {
     4     int _age;
     5 }
     6 @end
     7 
     8 @implementation Person
     9 @end
    10 
    11 @interface Student : Person
    12 {
    13     int _age;//此处重复声明成员变量_age
    14 }
    15 @end
    16 
    17 @implementation Student
    18 @end
    19 
    20 int main()
    21 {
    22     return 0;
    23 }

    报错:重复声明成员变量 _age

      2>父类中声明实现的方法,子类可以重复声明实现(如果要实现子类自己的功能,可以重写方法,本例重写了run方法)

    下面的代码是正确的

     1 #import <Foundation/Foundation.h>
     2 @interface Person : NSObject
     3 {
     4     int _age;
     5 }
     6 - (void)run;
     7 @end
     8 
     9 @implementation Person
    10 - (void)run
    11 {
    12     NSLog(@"Person---跑");
    13 }
    14 @end
    15 
    16 @interface Student : Person
    17 
    18 - (void)run;
    19 @end
    20 
    21 @implementation Student
    22 - (void)run
    23 {
    24     NSLog(@"Student---跑");
    25 }
    26 @end
    27 
    28 int main()
    29 {
    30     return 0;
    31 }

      3>自己可以在不改变父类原有成员变量和方法的情况,拓充自己的成员变量和方法

    代码如下:

     1 #import <Foundation/Foundation.h>
     2 @interface Person : NSObject
     3 {
     4     int _age;
     5 }
     6 - (void)run;
     7 @end
     8 
     9 @implementation Person
    10 - (void)run
    11 {
    12     NSLog(@"Person---跑");
    13 }
    14 @end
    15 
    16 @interface Student : Person
    17 {
    18     int _weight;//子类拓充的成员变量,父类中没有
    19 }
    20 
    21 - (void)run;
    22 - (void)eat;//子类拓充的方法,父类中没有
    23 @end
    24 
    25 @implementation Student
    26 - (void)run
    27 {
    28     NSLog(@"Student---跑");
    29 }
    30 - (void)eat
    31 {
    32     NSLog(@"Student---吃");
    33 }
    34 @end
    35 
    36 int main()
    37 {
    38     return 0;
    39 }

    3、方法的访问

     1 #import <Foundation/Foundation.h>
     2 @interface Person : NSObject
     3 {
     4     int _age;
     5 }
     6 - (void)run;
     7 @end
     8 
     9 @implementation Person
    10 - (void)run
    11 {
    12     NSLog(@"Person---跑");
    13 }
    14 @end
    15 
    16 @interface Student : Person
    17 @end
    18 
    19 @implementation Student
    20 @end
    21 
    22 int main()
    23 {
    24     Student *s = [Student new];
    25     [s run];
    26     return 0;
    27 }

    原理:每个对象中隐藏着一个isa指针,每个类中隐藏着一个superclass指针

    (1)当对象s调用run方法,通过隐藏的isa指针优先去s对应的Student类中去寻找run方法;

    (2)当在Student类中没有找找run方法时,就会通过superclass指针去父类Person中寻找run方法;

    (3)在父类中招到了run方法,执行之;如果没找到,会一直往上找直到NSObject类。

    当执行第25行代码的时候,对象s调用run方法,它会优先去当前对象所对应的类中去寻找run方法,发现子类中没有run方法,它就会去父类中找run方法

    如果一直找不到就会报经典错误。

    执行结果如下:

    4、方法的重写

      子类重新实现父类中已经存在的某个方法,覆盖父类以前的做法

     1 #import <Foundation/Foundation.h>
     2 @interface Person : NSObject
     3 {
     4     int _age;
     5 }
     6 - (void)run;
     7 @end
     8 
     9 @implementation Person
    10 - (void)run
    11 {
    12     NSLog(@"Person---跑");
    13 }
    14 @end
    15 
    16 @interface Student : Person
    17 - (void)run;
    18 @end
    19 
    20 @implementation Student
    21 - (void)run//重写:子类重新实现父类中的某个方法,覆盖掉父类以前的做法
    22 {
    23     NSLog(@"Student---跑");
    24 }
    25 @end
    26 
    27 int main()
    28 {
    29     Student *s = [Student new];
    30     [s run];
    31     return 0;
    32 }

    总结:

    (1)父类必须声在子类的前面

    (2)不允许子类和父类拥有相同名称的成员变量

    (3)允许子类对父类中的方法进行重复声明和实现

    (4)找方法:当调用方法时,优先去当前类中去找,找不到了再去父类找

    (5)方法重写:子类重新实现父类中已经存在的某个方法,覆盖父类以前的做法

    人生之路,不忘初心,勿忘始终!
  • 相关阅读:
    自适应高度的 文本框
    点击小图片遮罩显示大图片
    C++中的声明与定义
    LeetCode_Bit Manipulation
    “纯”面向对象
    指针和引用
    new和delete用法小结
    C++中的变量属性小结
    C++的一些黑暗料理
    Python中的字典和集合
  • 原文地址:https://www.cnblogs.com/xdl745464047/p/3999625.html
Copyright © 2011-2022 走看看