java之继承总结(文字版)

本文探讨了继承在提高代码复用性和实现多态方面的作用,并分析了子类对象内存布局及如何通过super访问父类成员。此外,还讨论了Java为何不支持多继承,以及Object类的toString方法如何操作子类数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承的好处:
    1.提高了代码的复用性.(源代码级别的;)     ------> 当发现两个类有大量相同代码时,可考虑向上提取,使用继承,增加代码复用;             1.1  功能的积累,其实也是一种代码的复用  ------>当发现新功能在原有功能基础上增强时,可考虑使用继承,增加代码复用;
    2.让类与类之间产生了关系,给第三个特征多态提供了前提,没有继承就没有多态(暂不考虑接口时)  ----->使用继承,进而使用多态时;
    3.特点:子类继承了父类,在子类的每个对象中划分了两块内存区域,一块是放了父类的堆中成员(因为这个时候并没有产生父类对象,所以我们不说 父类对象的成员 ),一块是放了子类对象本身的堆中成员.
            
            子类对象地址是:0x0045 在堆内存中子类对象被分成了两份空间:
                 Zi空间 (this持有引用),
                 Fi空间 (super持有引用),
                                    堆内存:
                                    _________________________________
                    0x0045     |  new Zi() :                               |
                                    |   ____________    ____________     |
                                    |  |                  |  |                    |   |
                                    |  |                  |  |                    |   |
                                    |  |   Zi空间     |  |   Fu空间      |   |
                                    |  |                  |  |                    |   |
                                    |  |                  |  |                    |   |
                                    |  |____________|  |___________  _|   |
                                    |____________________________ ____|
                                    
        
    
问题:
  1,创建子类对象时,子类构造会默认调用父类空参构造,此时是否创建了父类对象(已知每一个子类对象继承的父类字段都是惟一的)?
       答: 没有.
        因为子类继承父类之后,在创建子类对象时,虽然在子类构造中会默认调用父类空参构造,但此时不会创建父类对象,只是会把父类成员打包一份放在子类对象所在内存区域,并用super做标记.这样子类就可以通过super访问父 类中非私有的成员,但其实这些成员封装在子类对象中,并没有单独创建父类对象.
        
        从代码的抽取性这个意义上来说:
            继承的抽取性是 :源代码级别的;
                也就是说继承只是让我们在写源代码时减少了相同代码的书写,而在内存中可以说是并没有减少内存的占用,(甚至说相反可能会增加内存的占用),因为子类对象中本来该有的,都会通过从父类获取,最终保存在子类在堆内存所开辟的空间内;
           static 的抽取性是 :内存级别的;
                   也就是说静态修饰,并没有改变我们源代码书写量,但是在内存上却将原来在堆内存中大量重复的部分,进行抽取,只保留一份放在方法区中的静态区,供所有对象共享,减少了内存空间不必要的消耗.
                   
java中支持单继承,不直接支持多继承,但对c++中的多继承机制进行了改良.        
问题:
    1.java中不直接支持多继承的原因是什么?
       答:举个例子来说:如果[ class C extends A,B ] 当A ,B 有声明完全一样的方法时,C中又没有重写
       (覆盖)该方法,当C 的对象调用该方法时,它不知道到底应该调用 A类中的还是 B类中的方法,此时会产生调用的不确定性,所以java中为了避免这种不确定性,不直接支持多继承; ps:但是java对c++中的多继承机制进行了改良: 通过定义接口,而接口可以多实现,也可以多继承(变相做到了多继承),并且接口要求子类必须 重写(覆盖)其所有方法,所以在子类调用方法时,即便是父类接口中有声明完全一样的方法,子类调用时,实际调用的是子类中的方法,就不会出现调用的不确定性.
           
     2.子类继承父类时,子类对象调用父类方法时,父类的方法都只局限于操作父类的数据;而我们随便定义一个类,创建子类对象调用了toString()方法时,这个方法返回了子类对象本身的地址值,也就是说父类(Object)的方法操作到了子类对象自身的数据,这个是如何做到的?     
          答:这个其实是错觉:我们首先看object中tostring:
          public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
        其实是toString()里边的以下两个方法在作怪:
         public final native Class<?> getClass();
         public native int hashCode();
        它们都被native修饰,都是本地方法,调用了底层的一些方法,所以它可以获得所有东西也就不奇怪了.
       
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值