首页 > 代码库 > 黑马程序员 07-继承使用过程中的注意点(含代码)

黑马程序员 07-继承使用过程中的注意点(含代码)

———Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ———

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

 1 #import <Foundation/Foundation.h> 2 @interface Student : Person 3 @end 4  5 @implementation Student 6 @end 7  8 @interface Person : NSObject 9 @end10 11 @implementation Person12 @end13 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 @end10 11 @implementation Student12 @end13 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 @end10 11 @interface Student : Person12 {13     int _age;//此处重复声明成员变量_age14 }15 @end16 17 @implementation Student18 @end19 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 Person10 - (void)run11 {12     NSLog(@"Person---跑");13 }14 @end15 16 @interface Student : Person17 18 - (void)run;19 @end20 21 @implementation Student22 - (void)run23 {24     NSLog(@"Student---跑");25 }26 @end27 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 Person10 - (void)run11 {12     NSLog(@"Person---跑");13 }14 @end15 16 @interface Student : Person17 {18     int _weight;//子类拓充的成员变量,父类中没有19 }20 21 - (void)run;22 - (void)eat;//子类拓充的方法,父类中没有23 @end24 25 @implementation Student26 - (void)run27 {28     NSLog(@"Student---跑");29 }30 - (void)eat31 {32     NSLog(@"Student---吃");33 }34 @end35 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 Person10 - (void)run11 {12     NSLog(@"Person---跑");13 }14 @end15 16 @interface Student : Person17 @end18 19 @implementation Student20 @end21 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 Person10 - (void)run11 {12     NSLog(@"Person---跑");13 }14 @end15 16 @interface Student : Person17 - (void)run;18 @end19 20 @implementation Student21 - (void)run//重写:子类重新实现父类中的某个方法,覆盖掉父类以前的做法22 {23     NSLog(@"Student---跑");24 }25 @end26 27 int main()28 {29     Student *s = [Student new];30     [s run];31     return 0;32 }

 

 

总结:

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

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

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

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

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

黑马程序员 07-继承使用过程中的注意点(含代码)