黑马程序员技术交流社区

标题: 老毕视频中多态特点的一个疑问 [打印本页]

作者: 杨建聪    时间: 2013-1-5 17:05
标题: 老毕视频中多态特点的一个疑问
本帖最后由 张向辉 于 2013-1-16 11:28 编辑

多态特点之一:在多态中,静态函数的特点,无论编译和运行,都参考左边。

关于这个特点的理解,有没例子?想了很久,怎么想也想不明白。。。。。。。。
作者: 冉世友    时间: 2013-1-5 17:14
看可不可以这样理解:

多态得到的是父类的引用,父类里的静态方法在父类被类加载器加载的时候就
存在于方法区了,父类的引用就运行自己的静态方法了。如果是子类的引用,那就
运行子类覆盖后的静态方法了。
作者: 杨建聪    时间: 2013-1-5 17:18
冉世友 发表于 2013-1-5 17:14
看可不可以这样理解:

多态得到的是父类的引用,父类里的静态方法在父类被类加载器加载的时候就

这样的话多态就没什么意思了,按照你这个理解,静态函数就不可以多态了
作者: 肖志锋    时间: 2013-1-5 19:22
。。。你说对了,静态的就是不能多态。。老毕那么说就是免得我们迷糊,就没去分开了,属性,静态的方法,构造函数都是不能多态的。
属性和静态方法,你就看是谁的引用,那就是谁的了。
作者: 何竹冬    时间: 2013-1-5 20:17
你好
静态是优先于对象存在的所以类名调用静态成员的时候是调用引用所属类的静态成员变量或方法。
  1. class Person
  2. {
  3.         public static int a=1;
  4.         public static void eat()
  5.         {
  6.                 System.out.println("person eat");
  7.         }
  8. }

  9. class Student extends Person
  10. {
  11.         public static int a=2;
  12.         public static void eat()
  13.         {
  14.                 System.out.println("student eat");
  15.         }
  16. }

  17. public class Test
  18. {
  19.         public static void main(String[] args) throws Exception
  20.         {
  21.                 Person p = new Student();
  22.                 System.out.println(p.a);
  23.                 p.eat();
  24.         }
  25. }
复制代码
打印结果是:

1

person eat
作者: 余勇    时间: 2013-1-6 23:30
肖志锋 发表于 2013-1-5 19:22
。。。你说对了,静态的就是不能多态。。老毕那么说就是免得我们迷糊,就没去分开了,属性,静态的方法,构 ...

我刚看到这,的确是这样,就是静态的特点决定的。
作者: 徐帅    时间: 2013-1-7 09:54
本帖最后由 徐帅 于 2013-1-7 10:00 编辑

多态中(父类引用指向子类对象)成员的特点
1 非静态成员函数的特点:(因为存在覆盖)
  1> 在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
  2> 在运行时期:参阅对象所属的类中是否有调用的方法。
(动态绑定:this所指对象去调用方法)
   简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
2. 成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。
3. 静态成员函数的特点:无论编译和运行,都参考做左边。
(静态绑定:静态方法一进内存就绑定在其所属类上了,所属于类)
原因:静态方法不需要对象,其决定于引用变量的所属类,所以一般不会覆盖静态方法。

我们首先要明白多态的前提:  必须是类与类之间有关系。要么继承,要么实现。 通常还有一个前提:存在覆盖。   

对于楼主的问题,问题的关键是
   静态成员所属于类,静态方法调用不需要对象,一般也不会去覆盖,编译器能够直接发现这个类是否有方法,因为静态一加载就进内存了,
   而非静态成员需要对象去调用。

非静态成员调用时:
编译期:如果父类都没有这个方法,又如何谈得上覆盖呢,因为只有运行时才知道是否进行了覆盖,而编译器无法知道,所以当父类中没有该方法时,
              为了安全起见,编译器就认为错误。
在运行时期:由于是动态绑定,this所指对象去调用方法,当然运行子类所覆盖的方法了,所以运行时看子类。

不知道理解得对不对,希望各位拍砖






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2