0%

前期绑定和后期绑定的经典例子

一、简单例子

com.dslztx.package1包下代码:

1
2
3
4
5
6
7
8
package com.dslztx.package1;

public class A {

public int a = 100;

int b = 100;
}

com.dslztx.package2包下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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,打印50
System.out.println(b.a);

A a = new B();

//前期绑定:绑定到A.a,打印100
System.out.println(a.a);

C c = new C();

//前期绑定:绑定C.b,打印60
System.out.println(c.b);

A aa = new C();

//前期绑定:绑定A.a,打印100
System.out.println(aa.a);
}
}

class C extends A {

int b = 60;

private int a = 60;
}

运行结果如下:

1
2
3
4
50
100
60
100

二、基于后期绑定突破访问控制

访问控制判断只在编译期进行,因此可采用“前期绑定绑定到可通过访问控制的方法,后期绑定绑定到本不可通过访问控制的方法”的方式在运行期突破访问控制。
chapter8.package1包下代码:

1
2
3
4
5
6
7
8
package chapter8.package1;

public class A {

protected void f() {
System.out.println("Hello");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package chapter8.package1;

import chapter8.package2.B;

public class C {

public static void print(A a) {
a.f();
}

public static void main(String[] args) {
B b = new B();
//不能直接访问该方法
//b.f();

//通过多态访问了本不能访问的方法
print(b);
}
}

chapter8.package2包下代码:

1
2
3
4
5
6
7
8
9
10
package chapter8.package2;

import chapter8.package1.A;

public class B extends A {

protected void f() {
System.out.println("World");
}
}

运行结果如下:

1
World

三、构造器方法调用过程中的多态

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.dslztx.package1;

class Glyph {

Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}

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

class RoundGlyph extends Glyph {

private int radius = 1;

RoundGlyph(int r) {
radius = r;
System.out.println("RoundGlyph.RoundGlyph(),radius=" + radius);
}

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

public class PolyConstructors {

public static void main(String[] args) {
new RoundGlyph(5);
}
}

运行结果如下:

1
2
3
4
Glyph() before draw()
RoundGlyph.draw(),radius=0
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius=5

四、后期绑定的递归

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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");
}
}

运行结果如下:

1
Child

五、非覆盖被误以为覆盖

由于E中的f()g()方法不能被F继承,因此E中的f()方法和F中的f()方法不是“被覆盖”和“覆盖”的关系,E中的g()方法和F中的g()方法也不是“被覆盖”和“覆盖”的关系,进而导致E中的f()g()方法不能被后期绑定到F中的f()g()方法。
com.dslztx.package3包下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.dslztx.package3;

import com.dslztx.package2.F;

public class E {

public static void main(String[] args) {
E e = new F();
e.f();
e.g();
}

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

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

com.dslztx.package2包下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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");
}
}

运行结果如下:

1
2
Hello
Hello
您的支持将鼓励我继续分享!