多态:对象有多种表现形式,具体最终使用哪种形式由最后运行时情况决定。
使用多态必须要达到三个条件:
- 一个就是需要使用继承
- 一个就是涉及方法的重写
- 最后一个就是需要进行向上转型
前期绑定:也叫编译时绑定,主要表现类型是重载(overloading),比如一个类中有一个或多个名称相同的方法,但是他们参数不同,举个例子:
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),比如子类重写了父类的方法,举个例子:
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属性。举个例子:
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方法)之外的其他方法属于后期绑定,运行时能判断对象的类型进行绑定。来个例子:
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)。来个例子:
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属性的,所以不支持多态。当时基类的构造器总是在子类的构造过程中被调用,而且按照继承层次逐级依次调用。举个例子:
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的三大特性之一,多态在实际项目过程的使用会非常广泛,上述说明还需要在实践中多加锻炼才行。
长按关注「我在编程」
多看 | 多想 | 多练
实践是检验真理的唯一标准