Java 三大特性之多态

大家都知道 Java 的三大特性是:封装、继承和多态。今天要介绍的是 Java 三大特性之多态:对象有多种表现形式,具体最终使用哪种形式由最后运行时情况决定。

使用多态必须要达到三个条件:

  • 一个就是需要使用继承
  • 一个就是涉及方法的重写
  • 最后一个就是需要进行向上转型

前期绑定:也叫编译时绑定,主要表现类型是重载(overloading),比如一个类中有一个或多个名称相同的方法,但是他们参数不同。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestClass {
public static void main(String[] str) {
testMethod(10);
testMethod("This is a string");
}
public static void testMethod(int iRet) {
System.out.println("int simple");
}
public static void testMethod(String sRet) {
System.out.println("string simple");
}
}

输出结果:

int simple
string simple

后期绑定:也叫运行时绑定,主要表现类型就是重写(overriding),比如子类重写了父类的方法。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TestClass {
public static void main(String[] str) {
Father testMethod = new Son();
testMethod.getResult();
}
}
class Father {
public void getResult() {
System.out.println("I am a Father");
}
}
class Son extends Father {
public void getResult() {
System.out.println("I am the Son");
}
}

输出结果为:

I am the Son

只有普通的方法调用是可以多态的,直接访问的成员变量是不支持多态的。为了避免混淆,可以把成员变量设置为 private 属性。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class TestClass {
public static void main(String[] str) {
Father testMethod = new Son();
System.out.println("testMethod.notMethod = " +
testMethod.notMethod +
", testMethod.getNotMethod() = " +
testMethod.getNotMethod());
}
}
class Father {
public int notMethod = 0;
public int getNotMethod() {
return notMethod;
}
}
class Son extends Father {
public int notMethod = 1;
public int getNotMethod() {
return notMethod;
}
}

输出结果:

testMethod.notMethod = 0, testMethod.getNotMethod() = 1

**从结果可以看出来,testMethod.notMethod 获取的是父类的变量的值,而不是子类的,但是 testMethod.getNotMethod() 则是获取子类的方法的返回值。

总结下就是,static 方法和 final 方法属于前期绑定,子类无法重写 final 方法,静态和非静态的成员变量都属于前期绑定。除了 static 方法和 final 方法( private 属于 final 方法)之外的其他方法属于后期绑定,运行时能判断对象的类型进行绑定。**

来个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TestClass {
public static void main(String[] str) {
Father testMethod = new Son();
testMethod.getResult();
}
}
class Father {
public static void getResult() {
System.out.println("I am a Father");
}
}
class Son extends Father {
public static void getResult() {
System.out.println("I am the Son");
}
}

输出结果为:

I am a Father

当继承和向上转型同时存在时,函数实现会遵循多态原则进行实际的调用,调用顺序为:this.method(class)、super.method(class)、this.method((super)class)、super.method((super)class)。

来个例子:

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
38
39
40
41
public class TestClass {
public static void main(String[] str) {
Father oneTest = new Father();
Son twoTest = new Son();
Father threeTest = new Son();
Son fourTest = new GrandDaughter();
//this.method(class)
threeTest.method(oneTest);
//super.method(class)
threeTest.method(twoTest);
//this.method((super)class)
threeTest.method(threeTest);
//super.method((super)class)
threeTest.method(fourTest);
}
}
class Father {
public void method(GrandDaughter grandDaughter) {
System.out.println("I am the Granddaughter in Father");
}
public void method(Son son) {
System.out.println("I am the son in Father");
}
public void method(Father father) {
System.out.println("I am the Father in father");
}
}
class Son extends Father {
public void method(Father father) {
System.out.println("I am the Father in Son");
}
}
class GrandDaughter extends Son {
}

输出结果为:

I am the Father in Son
I am the son in Father
I am the Father in Son
I am the son in Father

构造器方法默认都是 static 属性的,所以不支持多态。当时基类的构造器总是在子类的构造过程中被调用,而且按照继承层次逐级依次调用。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class TestClass extends GouZaoQiThree{
public static void main(String[] str) {
new TestClass();
}
}
class GouZaoQiOne {
GouZaoQiOne() {
System.out.println("This is GouZaoQiOne");
}
}
class GouZaoQiTwo extends GouZaoQiOne{
GouZaoQiTwo() {
System.out.println("This is a GouZaoQiTwo");
}
}
class GouZaoQiThree extends GouZaoQiTwo{
GouZaoQiThree(){
System.out.println("This is GouZaoQiThree");
}
}

输出结果:

This is GouZaoQiOne
This is a GouZaoQiTwo
This is GouZaoQiThree

好了,作为 Java 的三大特性之一,多态在实际项目过程的使用会非常广泛,上述说明还需要在实践中多加锻炼才行。

sylan215 wechat
十年测试老鸟的原创干货,扫码关注我,一起涨姿势

相关文章: