关闭

Java中前期绑定和后期绑定的一些经典例子

293人阅读 评论(0) 收藏 举报
分类:
1、关于数据成员前期绑定的一个例子
理论点:见《Java的前期绑定和后期绑定》
代码内容如下:
package com.dslztx.package1;

public class A {
    public int a = 100;

    int b = 100;
}
package com.dslztx.package2;
import com.dslztx.package1.A;

public class B extends A {
    private int a = 50;

    public static void main(String[] args) {
        B b = new B();
        //"b.a"最后绑定的是"private int a = 50;(定义地址:package2:B,目标地址:package2:B)"
        System.out.println(b.a);

        A a = new B();
        //"a.a"最后绑定的是"public int a = 100;(定义地址:package1:A,目标地址:package1:A)"
        System.out.println(a.a);

        C c = new C();
        //"c.a"最后绑定的是"private int a = 60;(定义地址:package2:C,目标地址:package2:C)",接着进行访问控制判断(注意这里的访问者地址是:package2:B,而不是:package2:C),不能访问,编译出错
        //System.out.println(c.a);

        //"c.b"最后绑定的是"int b = 60;(定义地址:package2:C,目标地址:package2:C)"
        System.out.println(c.b);

        A aa = new C();
         //"aa.a"最后绑定的是"public int a = 100;(定义地址:package1:A,目标地址:package1:A)"
        System.out.println(aa.a);
    }
}

class C extends A {
    private int a = 60;
    
    int b = 60;
}
类B运行后,结果如图1所示:
                                           图1


2、构造器方法调用过程中的多态现象
理论点:初始化顺序+一般方法的多态
代码内容如下:[1]

package com.dslztx.package1;

class Glyph {
    void draw() {
        System.out.println("Glyph.draw()");
    }

    Glyph() {
     //以下被标记为A语句块
        System.out.println("Glyph() before draw()");
        draw();
        System.out.println("Glyph() after draw()");
    }
}

class RoundGlyph extends Glyph {
    private int radius = 1;

    RoundGlyph(int r) {
     //以下被标记为B语句块
        radius = r;
        System.out.println("RoundGlyph.RoundGlyph(),radius=" + radius);
    }

    void draw() {
        System.out.println("RoundGlyph.draw(),radius=" + radius);
    }
}

/**
 * 0、注意以下不包括静态初始化过程
 * 1、首先生成RoundGlyph的实例和被包含的Glyph的实例,一旦生成好它们的实例,紧接着进行它们的非静态数据成员的默认初始化,因此radius=0
 * 2、执行RoundGlyph()构造方法
 * 2.1、首先调用父类Glyph的构造方法
 * 2.1.1、Glyph没有父类,调用Glyph父类构造方法没有效果(这里不考虑Object类)
 * 2.1.2、触发Glyph类"非静态数据成员定义初始化"的语句
 * 2.1.3、触发Glyph类"非静态数据成员初始化语句"的语句
 * 2.1.4、执行A语句块,当执行"draw()"方法,结合后期绑定的具体策略,最终执行外围子实例(即RoundGlyph实例)的"draw()"方法,此时radius=0
 * 2.2、触发RoundGlyph类"非静态数据成员定义初始化"的语句
 * 2.3、触发RoundGlyph类"非静态数据成员初始化语句"的语句
 * 2.4、执行B语句块
 */
public class PolyConstructors {
    public static void main(String[] args) {
        new RoundGlyph(5);
    }
}
类PolyConstructors运行后,结果如图2所示:

                                        图2


3、3层关系的多态现象

理论点:多层继承关系下的多态,即后期绑定的递归
代码内容如下:
package com.dslztx.package1;

public class ThreeLevel {
    public static void main(String[] args) {
        GrandFather grandFather = new Child();
        grandFather.f();
    }
}

class GrandFather {
    public void f() {
        System.out.println("GrandFather");
    }
}

class Parent extends GrandFather {
}

class Child extends Parent {
    public void f() {
        System.out.println("Child");
    }
}

类ThreeLevel运行后,结果如图3所示:

                                            图3


4、后期绑定陷阱

以下例子中,E中的f()方法和F中的f()方法不是“被覆盖”和“覆盖”的关系,E中的g()方法和F中的g()方法也不是“被覆盖”和“覆盖”的关系。最后的运行结果见图4,表明没有多态行为。原因详见《Java的前期绑定和后期绑定》,跟其中的“二、后期绑定”下的例3相类似。

package com.dslztx.package3;
import com.dslztx.package2.F;

public class E {
    private void f() {
        System.out.println("Hello");
    }

    void g() {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        E e = new F();
        e.f();
        e.g();
    }
}
package com.dslztx.package2;
import com.dslztx.package3.E;

public class F extends E {
    public void f() {
        System.out.println("World");
    }

    public void g() {
        System.out.println("World");
    }
}
                                           图4




[1]摘自《Java编程思想》

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:468358次
    • 积分:7293
    • 等级:
    • 排名:第3022名
    • 原创:302篇
    • 转载:78篇
    • 译文:0篇
    • 评论:23条
    最新评论