黑马程序员技术交流社区

标题: 深入多态机制 [打印本页]

作者: liumeng    时间: 2012-2-29 14:28
标题: 深入多态机制
class Father {
        int a = 5;

        public void m1() {
                System.out.println("父类的方法");
        }

}

class Son extends Father {
        int a = 10;

        public void m1() {
                System.out.println("子类的方法");
        }

        public void m2() {

        }
}

public class MyTest {

        public static void main(String as[]) {
                Father f = new Son();
                System.out.println("a=" + f.a);
            f.m1();
        }
}
为什么a=5呢?不父类引用指向子类么
作者: 田啸    时间: 2012-2-29 14:52
在你的程序里SON继承了FATHER,对于 Father f = new Son();,首先程序会初始化FAHTER,再初始化SON,对于变量 a来说,引用变量就近原则来说呢,就会先引用FATHER类中的.
这里涉及到加载的顺序,我写了个小例子:
class A{
//int i=1;    //当访问时,才知道是否被初始化了
{
   int i=1;     
   System.out.println("------"+i);
}    //相当int i = 1,初始化时打印
public A(){
   System.out.println("A构造函数调用了`````");
}
public void go(){
   System.out.println("A----------------");
}
}

class B extends A{
{
   int i=2;
   System.out.println("*****"+i);
}
public B(){
   System.out.println("B构造函数调用了`````");
}
public void go(){
   System.out.println("B----------------");
}
}
public class Test {
public static void main(String[] args) {
   A a=new B();   System.out.println(a.i );   
}
}

----打印
------1
A构造函数调用了`````
*****2
B构造函数调用了`````    1

作者: 王--明    时间: 2012-2-29 14:59
本帖最后由 王--明 于 2012-2-29 15:01 编辑

简单先理解下多态的一些特点;
Father f = new Son();
这代表什么意思呢?
    很简单,它表示我定义了一个Father 类型的引用,指向新建的Son类型的对象。由于Son是继承自它的父类Father ,所以Father 类型的引用是可以指向Son类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,
定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

所以多态中调用方法的如下
   1:父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;:
     2:同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
     对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。
多态中变量如下
    1、使用父类类型的引用指向子类的对象;
  2、该引用只能调用父类中定义的方法和变量;
  3、变量不能被重写(覆盖),“重写”的概念只针对方法,如果在子类中“重写”了父类中的变量,那么在编译时会报错。
作者: 王国华    时间: 2012-2-29 15:31
本帖最后由 王国华 于 2012-2-29 15:32 编辑

在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
  在运行期间;参阅对象所属类中是否有调用的方法。
  简单总结就是:

  成员函数在多态调用时,编译看左边,运行看右边。

m1() 属于成员函数 所以覆盖了,方法变了

  成员变量的特点:
  无论编译和运行,都参考左边(引用类型变量所属的类)。

a属于成员变量 还是看父类的 所以a没变



  在多态中,静态成员函数的特点;
  无论编译和运行,都参考左边(引用类型变量所属的类)。

作者: 陈建凡    时间: 2012-2-29 15:43
Father f = new Son()在内存中做了!父类和 子类的实例化后,函数 都是在 方法区里面,而变量都存在 对内存中,当父类 指向子类的时候,就是父类 引用了子类方法区的函数,但是在 推内存的变量还是各自的,这样是自己理解的!哈




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