日期:2014-05-20  浏览次数:20698 次

Thingking In Java里一个对象构造顺序和向上转型的问题
一,向上转型:

Java code

结果:(我怎么理解的是注释的结果啊)
Frog swim
Frog speak
Frog eat
Frog grow
Frog eat            //Amphibian eat
Amphibian grow
Frog eat           // Amphibian eat



import static org.greggordon.tools.Print.*;

class Amphibian {
    protected void swim() {
        println("Amphibian swim");
    }
    protected void speak() {
        println("Amphibian speak");
    }
    void eat() {
        println("Amphibian eat");
    }
    static void grow(Amphibian a) {
        println("Amphibian grow");
        a.eat();
    }
}

public class Frog17 extends Amphibian {
    @Override protected void swim() {
        println("Frog swim");
    }
    @Override protected void speak() {
        println("Frog speak");
    }
    @Override void eat() {
        println("Frog eat");
    }
    static void grow(Amphibian a) {
        println("Frog grow");
        a.eat();
    }
    public static void main(String[] args) {
        Frog17 f = new Frog17();
        // call overridden base-class methods:
        f.swim();
        f.speak();
        f.eat();
        // upcast Frog17 to Amphibian argument:
        f.grow(f);
                   //调导出类的方法,f向上转型为基类型,然后导出类中a.eat()是不是应该调基类的eat()啊
        // upcast Frog17 to Amphibian and call Amphibian method:
        Amphibian.grow(f);//调基类方法,参数向上转型基类型,然后a.eat()不应该是掉基类的eat么
    }
}




二:构造顺序:
Java code

import static org.greggordon.tools.Print.*;

class Component1 {
    Component1() { println("Component1()"); }
}

class Component2 {
    Component2() { println("Component2()"); }
}

class Component3 {
    Component3() { println("Component3()"); }
}

class Root {
    Component1 c1root=new Component1() ;
    Component2 c2root;
    Component3 c3root;
    Root() { println("Root()"); }
}

class Stem extends Root {
    Component1 c1stem;
    Component2 c2stem=new Component2();
    Component3 c3stem;
    Stem() { println("Stem()"); }
    public static void main(String[] args) {
        Stem s = new Stem();
    }
}


创建s时,过程是怎样的,我理解的就是只处理构造方法啊。

------解决方案--------------------
第一题,由于多态的存在,无论一个引用上传了多少层,在使用上传后的引用时,JVM都会检查这个引用真正的类型是什么,比如你的程序中:
static void grow(Amphibian a) {
println("Amphibian grow");
a.eat();
 }
如果你传一个Amphibian的一个子类Frog17给参数a并调用grow()方法时,上传发生了。在执行到a.eat()时,JVM会检查a的真正的类型是什么(这就是动态绑定,也是多态的基础),JVM会得到a是Frog17类型,所以会执行Forg17类的eat()方法.
------解决方案--------------------
针对第二个问题:
输出结果顺序应该为:
Component1()
Root()
Component2()
Stem()
记住这一点就明白了:用类去new 一个对象时候,会去调用该类的构造方法,但是若该类是其他类的子类,会优先调用父类的构造方法,后再调用该类自己的构造方法,即父类的构造方法优先被调用原则。

说的有点笼统,可以体会下
------解决方案--------------------
关于lz的第二个问题
可以参考偶以前的帖子
感觉大家讨论的也比较彻底了
http://topic.csdn.net/u/20090625/14/766e4863-9b61-4e09-a6a7-a51a07a3d20d.html
------解决方案--------------------
探讨
关于lz的第二个问题
可以参考偶以前的帖子
感觉大家讨论的也比较彻底了
http://topic.csdn.net/u/20090625/14/766e4863-9b61-4e09-a6a7-a51a07a3d20d.html