首页 > 代码库 > 黑马程序员 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-继承使用过程中的注意点(含代码)