java吧 关注:1,297,053贴子:12,834,510

今天发现我把继承理解错了

只看楼主收藏回复

我本以为继承简单的理解就是子类拥有父类的方法,只不过没显示,结果这个dog调用getM返回的是父类的m值,而不是我期望的子类的值。我想问问大佬们,是不是方法在谁那里定义就是调用谁的成员变量来用啊。



来自Android客户端1楼2022-11-14 13:55回复
    别想那么复杂,就是静态绑定和动态绑定区别。
    方法是动态绑定的,也就是运行的时候会根据你实际的类型去找对应的方法。比如你B继承了A重写了里面的方法。即使你声明B实际是A,这就是多态。
    变量这种是静态绑定的,也就是说你声明的什么类型,就去取对应的值。


    IP属地:湖南来自Android客户端2楼2022-11-14 14:41
    收起回复
      2026-02-07 00:15:52
      广告
      不感兴趣
      开通SVIP免广告
      要看成员变量怎么调用吧,默认应该就是this.成员变量


      IP属地:浙江来自Android客户端3楼2022-11-14 14:43
      回复
        子类没有重写的话,就会调父类的getM


        IP属地:四川来自Android客户端5楼2022-11-14 16:03
        回复
          就近原则,子类重写就调用子类,没有就调用父类的


          IP属地:江苏来自iPhone客户端6楼2022-11-14 16:41
          收起回复
            同名变量不会被覆盖!不过不建议这么写。自己给自己找事


            IP属地:北京来自Android客户端8楼2022-11-14 17:27
            回复
              把动态绑定机制再看一下


              IP属地:广东来自Android客户端9楼2022-11-14 17:30
              回复
                就近原则啊


                IP属地:四川来自Android客户端10楼2022-11-14 17:45
                回复
                  2026-02-07 00:09:52
                  广告
                  不感兴趣
                  开通SVIP免广告
                  ?咋感觉你把最基本的概念都弄错了,继承和动态绑定在回去看看


                  来自Android客户端11楼2022-11-15 00:17
                  回复
                    如果dog裡面重寫getM 那就返回m=6 ,如果想返回m=100就是getM裡面 return super getM


                    IP属地:中国澳门来自iPhone客户端12楼2022-11-15 00:32
                    回复
                      应该就是变量是静态绑定的所以在getM方法里返回的M就是Animal里的,而子类没有重写getM方法自然就会找父类的方法了。如果你在父类的getM里返回的是seeM()那么它返回的M值应该就是6了


                      IP属地:辽宁来自Android客户端13楼2022-11-15 00:55
                      回复
                        你好好看看你的子类都没有重写getm方法,当然去父类找啊


                        IP属地:河南来自Android客户端14楼2022-11-15 01:05
                        回复
                          emmm我试图用大白话描述一下继承
                          java的继承是一个overriding+hiding的机制,前者适用于 instance method, 后者则是 class method 与 field.
                          那么在外部试图访问父类的信息时,被hidden的尚可通过 Son.super.method() 或 ((Parent) son).field 重见天日;但被overridden后,没有些奇技淫巧是没法从son里调用parent.method()的
                          那么回到具体问题上,seeM() 在 Dog 中重新声明,那么 dog 与 animal 均“只能”访问子类方法,则双方同时有
                          this->seeM()存在
                          => return this->m
                          => sout 6
                          (抱歉点号的话会被转成“网页链接”)

                          而 getM() 仅在 Animal 中声明,则有
                          this->getM()不存在
                          => 查找 super->getM()
                          => return super->m
                          => sout 100

                          至于animal.m的100则属于之前提到的通过类型转换对 hidden fields 的访问,不再赘述
                          最后是一点碎碎念,不要这样声明变量,tutorials说的很明确了,Generally speaking, we don't recommend hiding fields as it makes code difficult to read.
                          非大白话资料 java tutorials 在这网页链接 Hidden Fields
                          java language specification 在这网页链接 method inheritence 在8.4.8 field declaration 在8.3 dynamic lookup 在 15.12.4
                          附加题 分别声明 static bark(), animal 与 dog 分别会怎么叫?


                          IP属地:日本来自Android客户端16楼2022-11-15 01:41
                          回复
                            劝退


                            来自Android客户端17楼2022-11-15 06:57
                            回复
                              2026-02-07 00:03:52
                              广告
                              不感兴趣
                              开通SVIP免广告
                              父类方法不能调用子类的变量,俩m不是一回事。


                              IP属地:湖北来自Android客户端18楼2022-11-15 09:02
                              回复