A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

question:1、 为什么子类的方法可以覆盖父类的方法,但是子类的常量不能覆盖父类的常量。
2、多态的机制是编译与运行时的对象发生变化了是吧,但是究竟运行时创造的是父类还是子类,如果是父类,为什么方法会被重写,如果是子类,为什么类成员变量AGE是父类的或者发生了其他的情况吗?谢谢

  1. class Parent
  2. {
  3.         public static String NAME = "我是父亲!";
  4.         public int AGE = 36;
  5.         public void earnMoney()
  6.         {
  7.            System.out.println("父亲能挣多钱!");
  8.             }
  9.         public void spendMoney()
  10.         {
  11.            System.out.println("父亲很节省!");
  12.              }
  13. }
  14. class Son extends Parent
  15. {
  16.         public static String NAME = "我是儿子";
  17.         public int AGE = 12;
  18.         public void spendMoney()
  19.         {  System.out.println("儿子很能花钱!");  }
  20.         public void play()
  21.         {  System.out.println("儿子很贪玩!");   }
  22. public static void main(String[] args)
  23.         {
  24.            Parent pa = new Son();//多态发生;
  25.            pa.spendMoney();//输出结果为“儿子很能花钱!”;
  26.            System.out.println("pa的年龄为:"+pa.AGE);//输出结果为:36;
  27.            pa.earnMoney();//输出结果为:父亲很能赚钱!;
  28.            System.out.println("Parent.NAME= "+Parent.NAME);
  29.            System.out.println("Son.NAME= "+Son.NAME);
  30.            //System.out.println( "强制转换父类方法:"+(Parent)pa.spendMoney );
  31.            //System.out.println("强制调取子类成员变量:"+(Son)pa.AGE);
  32.           
  33.          }
  34. }
复制代码


/**
结果为:

D:\>java Son
儿子很能花钱!
pa的年龄为:36
父亲能挣多钱!
Parent.NAME= 我是父亲!
Son.NAME= 我是儿子



*/

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1 神马都是浮云

查看全部评分

12 个回复

倒序浏览
第一:继承是子类自动共享父类中的属性和方法的一种机制,当子类中存在和父类一模一样的方法声明的函数时,会发生一个函数的特性:覆盖。

覆盖是函数的特性,而常量和变量是不具备这个特性的,所以不会有常量覆盖的情况。谁的引用就访问谁的属性。

在你这个例子中,使用的 NAME 是静态变量,静态变量是与类绑定的,直接通过类名就可以访问,与对象无关。

第二:这个问题涉及到继承时,内存中成员的变化。

继承时,相当于把父类中的所有属性和方法存储到了子类中,这些属性和方法都有它们的所属:super
当子类中有相同的属性或方法时,可以通过:super.属性 或 super.方法  的方式来区分。

多态是指父类或接口的引用指向其子类对象。内存中创建的是父类还是子类对象,关键是看 new  后面是谁。

如果父类引用指向父类对象,那就不是多态,它访问的是它自己的方法和属性。
如果是父类引用指向子类对象,那么就是多态,它只能使用覆盖了父类中的方法,不能使用自己的特有方法,只能使用从父类继承的属性,不能使用自己的特有属性。

这时,调用 pa.age 使用的是从父类中继承的AGE属性(相当于在子类中调用 super.AGE  , 因为变量不存在覆盖的情况)

方法是需要与对象进行绑定的,父类引用调用方法,但是指向的是子类对象,所以是先从子类中找方法,没有再找父类(虽然是在子类对象中找,但是父类引用是只能调用父类中的方法的,不能调用子类中特有的方法,否则会报错)。

调用 pa.spendMoney() 因为子类中覆盖了这个方法,所以使用的是子类中的方法
调用 pa.earnMoney() 因为子类中没有这个方法,找它的父类的方法。

以上是我的理解,不知道你能不能看懂,建议看一下毕老师的【多态的出现在成员调用上的特点】这个视频。

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 彭飞 于 2014-5-15 08:54 编辑

刚看到这个问题,
我也有点迷茫,哈哈。
不过捏,
继承我还是清楚,就是子类自动拥有父类的属性和方法,
并且具备覆盖的功效
然后我看你main方法的时候,突然灵光一闪,

想起毕老师讲课时候的总结。
多态,
非静态修饰的变量和方法,
编译时期看左边,运行时期看右边,
而静态方法和静态修饰的变量
编译时期看右边,运行也是看右边。

第一个、spendMoney()  非静态方法,输出子类运行结果。 正确
第二个、System.out.println("pa的年龄为:"+pa.AGE);AGE 静态的,输出父类值。正确。//问题修正【【成员变量是不存在覆盖现象的,AGE非静态,pa.AGE 就是在父类中调用 这个成员变量,是不存在覆盖现象的。】】
【【多谢楼主,要不然我会一直把这个问题忽略掉。。。】】
第三个、pa.earnMoney();  父类独有的方法。
第四个、 都是静态变量直接调用,
          System.out.println("Parent.NAME= "+Parent.NAME);
          System.out.println("Son.NAME= "+Son.NAME);
   
发现这个总结是真的好用啊,希望能帮到楼猪,同时自己也温习了。嘿嘿。

【静态 左边编译左运行--非静态左边右运行】



回复 使用道具 举报
蓝雨星空 发表于 2014-5-12 08:03
第一:继承是子类自动共享父类中的属性和方法的一种机制,当子类中存在和父类一模一样的方法声明的函数时, ...

谢谢哈,我对这篇文章的理解就是,发生多态时,编译时是父类,运行时是子类,但是这个子类只是具有子类的方法,属性全是父类的,调用的时候就是这样,我理解的没有错吧!
回复 使用道具 举报
彭飞 发表于 2014-5-12 10:05
刚看到这个问题,
我也有点迷茫,哈哈。
不过捏,

第二个、System.out.println("pa的年龄为:"+pa.AGE);AGE 静态的,输出父类值。正确。
第四个、 都是静态变量直接调用,
          System.out.println("Parent.NAME= "+Parent.NAME);
          System.out.println("Son.NAME= "+Son.NAME);

同学,NAME是静态的,但是AGE不是静态的,所以按照你的逻辑的话,age应该输出子类的……
回复 使用道具 举报
姜蕾蕾 发表于 2014-5-14 22:31
谢谢哈,我对这篇文章的理解就是,发生多态时,编译时是父类,运行时是子类,但是这个子类只是具有子类的 ...

子类可以有自己的特有方法和属性,但在多态中无法被调用到,因为之所以使用多态就是不确定后期使用的子类到底是哪一个,子类都不确定又怎么知道它具有哪些特有方法和属性呢?所以多态中只能调用从父类中继承到的方法和属性。如果要调用到子类中的特有方法和属性,就需要进行向下转型。
回复 使用道具 举报
彭飞 中级黑马 2014-5-15 09:00:25
7#
姜蕾蕾 发表于 2014-5-14 22:39
第二个、System.out.println("pa的年龄为:"+pa.AGE);AGE 静态的,输出父类值。正确。
第四个、 都是静态 ...

第二个、System.out.println("pa的年龄为:"+pa.AGE);AGE 静态的,输出父类值。正确。//问题修正
【【成员变量是不存在覆盖现象的,AGE非静态,pa.AGE 就是在父类中调用 这个成员变量,是不存在覆盖现象的。】】
【【多谢楼主,要不然我会一直把这个问题忽略掉。。。】】

我把总结修改了下:
方法:
【静态 左边编译左运行--非静态左边右运行】
成员变量:
【左边编译左边运行】
回复 使用道具 举报
蓝雨星空 发表于 2014-5-15 08:38
子类可以有自己的特有方法和属性,但在多态中无法被调用到,因为之所以使用多态就是不确定后期使用的子类 ...

今天问了一下传智的老师,答案很简单:多态时,成员方法编译时看左边,运行时看右边,其他所有的编译运行时都看左边……:handshake
回复 使用道具 举报
彭飞 发表于 2014-5-15 09:00
第二个、System.out.println("pa的年龄为:"+pa.AGE);AGE 静态的,输出父类值。正确。//问题修正
【【成 ...

今天问了一下传智的老师,答案很简单:多态时,成员方法编译时看左边,运行时看右边,其他所有的编译运行时都看左边……恭喜你答对了,哇咔咔咔咔……:handshake
回复 使用道具 举报
姜蕾蕾 发表于 2014-5-15 22:07
今天问了一下传智的老师,答案很简单:多态时,成员方法编译时看左边,运行时看右边,其他所有的编译运行 ...

多谢你帮我总结一下。。。。。。

这个问题,我也总算是根深蒂固了。
回复 使用道具 举报
彭飞 发表于 2014-5-15 22:15
多谢你帮我总结一下。。。。。。

这个问题,我也总算是根深蒂固了。

互帮互助,共同进步嘛,哈哈……
回复 使用道具 举报
姜蕾蕾 发表于 2014-5-15 22:17
互帮互助,共同进步嘛,哈哈……

嗯,
好的。
加油。
回复 使用道具 举报
还看不懂,要加油了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马