年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6033|回复: 0

子类中如何修改继承父类的private成员变量

[复制链接]
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

    发表于 2014-3-16 13:21:07 | 显示全部楼层 |阅读模式
    该示例重点要解决以下几个问题:
    1、private属性的成员变量,子类中是否存在该变量?
    2、如果不存在,继承的实质是继承哪些东西?如果存在,如果使用或修改该成员变量的值;
    3、深刻理解直接赋值与通过对象方法给成员变量赋值的区别;
    4、子类通过父类的方法来操作变量;
    5、方法的递归调用;

    一,定义一个Person类:
    Person.h
    1. //
    2. //  Person.h
    3. //  Xcode
    4. //
    5. //  Created by yusian on 14-3-15.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import <Foundation/Foundation.h>
    9. @interface Person : NSObject
    10. {
    11. // 1、定义两个私有成员变量,该变量只能在对象内部访问,外部包括子类不能直接访问该成员变量;
    12. // 2、该成员变量会被子类所继承,但在子类中不能直接访问自己的该成员变量,但可通过方法实现访问;
    13. // 3、子类中的方法同样无法直接操作继承下来的父类私有变量,只能通过父类的方法直接操作;
    14. // 4、所以子类的方法通过调用父类的方法来实现修改当前类的该成员变量;
    15. @private
    16.     int        _age;
    17. // 默认情况下成员变量属性即为保护的,外部不能直接访问,但在类内部及子类内部均可直接访问;
    18. @protected
    19.     int        _height;
    20.    
    21. }
    22. // 对这两个不同属性的变量声明set与get方法;
    23. - (void)setAge:(int)age;
    24. - (int)age;
    25. - (void)setHeight:(int)height;
    26. - (int)height;
    27. @end
    复制代码
    Person.m
    1. //
    2. //  Person.m
    3. //  Xcode
    4. //
    5. //  Created by yusian on 14-3-15.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import "Person.h"
    9. @implementation Person
    10. // Person类中set方法可直接对成员变量进行赋值
    11. - (void)setAge:(int)age
    12. {
    13.     // 标记Person类中直接对成员变量_age赋值
    14.     NSLog(@"Person类中:\t_age = age");
    15.    
    16.     _age = age;
    17. }
    18. - (int)age
    19. {
    20.     // 标记Person类中直接返回成员变量_age的值
    21.     NSLog(@"Person类中:\treturn _age");
    22.    
    23.     // 直接返回成员变量_age的值
    24.     return _age;
    25. }
    26. - (void)setHeight:(int)height
    27. {
    28.     NSLog(@"Perons类中:\t_height = height");
    29.    
    30.     // Person类中直接给成员变量_height赋值
    31.     _height = height;
    32.    
    33. }
    34. - (int)height
    35. {
    36.     NSLog(@"Perons类中:\treturn _height");
    37.    
    38.     // 直接返回成员变量_height的值
    39.     return _height;
    40. }
    41. @end
    复制代码
    二、Student子类,继承父类Person:
    Student.h
    1. //
    2. //  Student.h
    3. //  Xcode
    4. //
    5. //  Created by yusian on 14-3-15.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import "Person.h"
    9. @interface Student : Person
    10. @end
    复制代码
    Student.m
    1. //
    2. //  Student.m
    3. //  Xcode
    4. //
    5. //  Created by yusian on 14-3-15.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import "Student.h"
    9. @implementation Student
    10. - (void)setAge:(int)age
    11. {
    12.     // 标记Student类中调用父类的setAge方法给_age赋值;
    13.     NSLog(@"Student类中:\t调用父类的setAge方法给成员变量_age赋值");
    14.    
    15.     // 调用父类中的setAge方法给_age赋值
    16.     [super setAge:age];
    17.    
    18.     // Student类中直接给成员变量_height赋值175
    19.     _height = 175;
    20. }
    21. - (int)age
    22. {
    23.     // 标记Student类中调用父类的getAge方法获取_age的值
    24.     NSLog(@"Student类中:\t调用父类的getAge方法获取_age的值");
    25.    
    26.     // 调用父类的getAge方法获取成员变量_age的值
    27.     return [super age];
    28.    
    29. }
    30. @end
    复制代码
    三、Boy子类,继承父类Student:
    Boy.h
    1. //
    2. //  Boy.h
    3. //  Xcode
    4. //
    5. //  Created by yusian on 14-3-15.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import "Student.h"
    9. @interface Boy : Student
    10. @end
    复制代码
    Boy.m
    1. //
    2. //  Boy.m
    3. //  Xcode
    4. //
    5. //  Created by yusian on 14-3-15.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import "Boy.h"
    9. @implementation Boy
    10. - (void)setAge:(int)age
    11. {
    12.     // 标记Boy类中调用父类的setAge方法给成员变量_age赋值
    13.     NSLog(@"Boy类中: \t调用父类的setAge方法给成员变量_age赋值");
    14.    
    15.     // 调用父类的setAge方法给成员变量_age赋值
    16.     [super setAge:age];
    17.    
    18.     // Boy类中直接给成员变量_height赋值174
    19.     _height = 174;
    20.    
    21. }
    22. - (int)age
    23. {
    24.     // 标记Boy类中调用父类的getAge方法获取age的值
    25.     NSLog(@"Boy类中: \t调用父类的getAge方法获取_age的值");
    26.    
    27.     return [super age];
    28. }
    29. @end
    复制代码
    main函数:
    1. //
    2. //  main.m
    3. //  Xcode
    4. //
    5. //  Created by yusian on 14-3-15.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import <Foundation/Foundation.h>
    9. #import "Person.h"
    10. #import "Student.h"
    11. #import "Boy.h"
    12. int main()
    13. {
    14.     // 创建一个男孩对象
    15.     Boy * boy = [Boy new];
    16.    
    17.     NSLog(@"Main函数中设置Boy类中_height的值");
    18.    
    19.     [boy setHeight:173];
    20.    
    21.     NSLog(@"Main函数中获取Boy类中_height的值");
    22.    
    23.     // Boy类中没有height的实现,所以实际上调用的是父类的方法
    24.     int h = [boy height];
    25.    
    26.     NSLog(@"Main函数中设置Boy类中_age的值为12");
    27.    
    28.     [boy setAge:12];
    29.    
    30.     NSLog(@"Main函数中获取Boy类中_age的值");
    31.    
    32.     int a = [boy age];
    33. //    int h = [boy height];
    34.    
    35.     // 打印男孩身高值
    36.     NSLog(@"输出最终结果:_height = %d", h);
    37.    
    38.     // 打印男孩年龄值
    39.     NSLog(@"输出最终结果:_age =  %d", a);
    40.     return 0;
    41. }
    复制代码
    输出结果:
    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、另一方面说明子类重写父类的方法并没有将父类的方法覆盖,确切地说是覆盖了属于自己的继承了父类的那个方法,属于父类的那个方法依然存在甚至可以调用,子类实际上是无权修改父类方法的。





    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|小黑屋|Archiver|iOS开发笔记 ( 湘ICP备14010846号 )

    GMT+8, 2024-4-28 01:04 , Processed in 0.054885 second(s), 23 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表