该示例重点要解决以下几个问题:
1、private属性的成员变量,子类中是否存在该变量?
2、如果不存在,继承的实质是继承哪些东西?如果存在,如果使用或修改该成员变量的值;
3、深刻理解直接赋值与通过对象方法给成员变量赋值的区别;
4、子类通过父类的方法来操作变量;
5、方法的递归调用;
一,定义一个Person类:
Person.h- //
- // Person.h
- // Xcode
- //
- // Created by yusian on 14-3-15.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- @interface Person : NSObject
- {
- // 1、定义两个私有成员变量,该变量只能在对象内部访问,外部包括子类不能直接访问该成员变量;
- // 2、该成员变量会被子类所继承,但在子类中不能直接访问自己的该成员变量,但可通过方法实现访问;
- // 3、子类中的方法同样无法直接操作继承下来的父类私有变量,只能通过父类的方法直接操作;
- // 4、所以子类的方法通过调用父类的方法来实现修改当前类的该成员变量;
- @private
- int _age;
- // 默认情况下成员变量属性即为保护的,外部不能直接访问,但在类内部及子类内部均可直接访问;
- @protected
- int _height;
-
- }
- // 对这两个不同属性的变量声明set与get方法;
- - (void)setAge:(int)age;
- - (int)age;
- - (void)setHeight:(int)height;
- - (int)height;
- @end
复制代码 Person.m- //
- // Person.m
- // Xcode
- //
- // Created by yusian on 14-3-15.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import "Person.h"
- @implementation Person
- // Person类中set方法可直接对成员变量进行赋值
- - (void)setAge:(int)age
- {
- // 标记Person类中直接对成员变量_age赋值
- NSLog(@"Person类中:\t_age = age");
-
- _age = age;
- }
- - (int)age
- {
- // 标记Person类中直接返回成员变量_age的值
- NSLog(@"Person类中:\treturn _age");
-
- // 直接返回成员变量_age的值
- return _age;
- }
- - (void)setHeight:(int)height
- {
- NSLog(@"Perons类中:\t_height = height");
-
- // Person类中直接给成员变量_height赋值
- _height = height;
-
- }
- - (int)height
- {
- NSLog(@"Perons类中:\treturn _height");
-
- // 直接返回成员变量_height的值
- return _height;
- }
- @end
复制代码 二、Student子类,继承父类Person:
Student.h
- //
- // Student.h
- // Xcode
- //
- // Created by yusian on 14-3-15.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import "Person.h"
- @interface Student : Person
- @end
复制代码 Student.m- //
- // Student.m
- // Xcode
- //
- // Created by yusian on 14-3-15.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import "Student.h"
- @implementation Student
- - (void)setAge:(int)age
- {
- // 标记Student类中调用父类的setAge方法给_age赋值;
- NSLog(@"Student类中:\t调用父类的setAge方法给成员变量_age赋值");
-
- // 调用父类中的setAge方法给_age赋值
- [super setAge:age];
-
- // Student类中直接给成员变量_height赋值175
- _height = 175;
- }
- - (int)age
- {
- // 标记Student类中调用父类的getAge方法获取_age的值
- NSLog(@"Student类中:\t调用父类的getAge方法获取_age的值");
-
- // 调用父类的getAge方法获取成员变量_age的值
- return [super age];
-
- }
- @end
复制代码 三、Boy子类,继承父类Student:
Boy.h- //
- // Boy.h
- // Xcode
- //
- // Created by yusian on 14-3-15.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import "Student.h"
- @interface Boy : Student
- @end
复制代码 Boy.m- //
- // Boy.m
- // Xcode
- //
- // Created by yusian on 14-3-15.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import "Boy.h"
- @implementation Boy
- - (void)setAge:(int)age
- {
- // 标记Boy类中调用父类的setAge方法给成员变量_age赋值
- NSLog(@"Boy类中: \t调用父类的setAge方法给成员变量_age赋值");
-
- // 调用父类的setAge方法给成员变量_age赋值
- [super setAge:age];
-
- // Boy类中直接给成员变量_height赋值174
- _height = 174;
-
- }
- - (int)age
- {
- // 标记Boy类中调用父类的getAge方法获取age的值
- NSLog(@"Boy类中: \t调用父类的getAge方法获取_age的值");
-
- return [super age];
- }
- @end
复制代码 main函数:- //
- // main.m
- // Xcode
- //
- // Created by yusian on 14-3-15.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import "Person.h"
- #import "Student.h"
- #import "Boy.h"
- int main()
- {
- // 创建一个男孩对象
- Boy * boy = [Boy new];
-
- NSLog(@"Main函数中设置Boy类中_height的值");
-
- [boy setHeight:173];
-
- NSLog(@"Main函数中获取Boy类中_height的值");
-
- // Boy类中没有height的实现,所以实际上调用的是父类的方法
- int h = [boy height];
-
- NSLog(@"Main函数中设置Boy类中_age的值为12");
-
- [boy setAge:12];
-
- NSLog(@"Main函数中获取Boy类中_age的值");
-
- int a = [boy age];
- // int h = [boy height];
-
- // 打印男孩身高值
- NSLog(@"输出最终结果:_height = %d", h);
-
- // 打印男孩年龄值
- NSLog(@"输出最终结果:_age = %d", a);
- return 0;
- }
复制代码 输出结果:
2014-03-16 12:59:12.032 Xcode[9075:303] Main函数中设置Boy类中_height的值
2014-03-16 12:59:12.034 Xcode[9075:303] Perons类中: _height = height
2014-03-16 12:59:12.034 Xcode[9075:303] Main函数中获取Boy类中_height的值
2014-03-16 12:59:12.035 Xcode[9075:303] Perons类中: return _height
2014-03-16 12:59:12.035 Xcode[9075:303] Main函数中设置Boy类中_age的值为12
2014-03-16 12:59:12.035 Xcode[9075:303] Boy类中: 调用父类的setAge方法给成员变量_age赋值
2014-03-16 12:59:12.036 Xcode[9075:303] Student类中: 调用父类的setAge方法给成员变量_age赋值
2014-03-16 12:59:12.036 Xcode[9075:303] Person类中: _age = age
2014-03-16 12:59:12.036 Xcode[9075:303] Main函数中获取Boy类中_age的值
2014-03-16 12:59:12.037 Xcode[9075:303] Boy类中: 调用父类的getAge方法获取_age的值
2014-03-16 12:59:12.037 Xcode[9075:303] Student类中: 调用父类的getAge方法获取_age的值
2014-03-16 12:59:12.037 Xcode[9075:303] Person类中: return _age
2014-03-16 12:59:12.038 Xcode[9075:303] 输出最终结果:_height = 173
2014-03-16 12:59:12.038 Xcode[9075:303] 输出最终结果:_age = 12
Program ended with exit code: 0
对于_height的值,程序中涉及到的主要有:
main函数中: [boy setHeight:173]; [boy setAge:12]; Boy类中: - (void)setAge:(int)age {
[super setAge:age]; _height = 174; }
Student类中: - (void)setAge:(int)age {
[super setAge:age]; _height = 175; }
Person类中: - (void)setHeight:(int)height { _height = height; }
整个过程中,_height分别被赋值为:173-->175-->174 [boy setHeight:173]:直接调用Person中的setHeight方法赋值为173; [boy setAge:12]: 1、这里涉及到递归调用,Boy类中的setAge方法调用了Student类中的setAge方法,Student类的setAge又调用了Person类中的setAge方法 2、为什么要这样做?因为_age为private属性,子类不能直接给_age赋值,而子类继承的父类方法都是直接赋值的方法,同样不能直接用来修改_age的值 3、父类Person中可以直接对_age进行赋值,所以通过递归的方式最终让父类的setAge方法修改_age的值。 4、这个过程说明了_age成员变量虽然是private,但同样会被子类所继承,但不能直接在子类中直接赋值,但可以调用父类的setAge方法赋值(调用父类的setAge方法不等于使用继承父类的setAge方法) 5、另一方面说明子类重写父类的方法并没有将父类的方法覆盖,确切地说是覆盖了属于自己的继承了父类的那个方法,属于父类的那个方法依然存在甚至可以调用,子类实际上是无权修改父类方法的。
|