多态实现的机制
Posted 戏路很宽丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多态实现的机制相关的知识,希望对你有一定的参考价值。
Java提供了编译时多态和运行时多态两种多态机制。前者是通过方法重载实现的,后者是通过方法的覆盖实现的。
在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式。
在Java语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类中的实例对象。同样,接口中的引用变量也可以指向其实现类的实例对象。而程序调用的方法在运行时期才动态绑定(绑定是指将一个方法调用和一个方法主体联系在一起),绑定的是引用变量所指向的具体实例对象的方法,也就是内存中正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。通过这种动态绑定实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法覆盖实现的多态也可以被称为运行时多态。
示例一:
1 public class Base { 2 public Base(){ 3 g(); 4 } 5 6 public void g() { 7 System.out.println("Base g()"); 8 } 9 10 public void f() { 11 System.out.println("Base f()"); 12 } 13 }
1 public class Derived extends Base{ 2 3 public void g() { 4 System.out.println("Derived g()"); 5 } 6 7 public void f() { 8 System.out.println("Derived f()"); 9 } 10 11 public static void main(String[] args) { 12 Base base=new Derived(); 13 base.f(); 14 base.g(); 15 } 16 }
程序运行结果:
在上面的例子中,由于子类Derived的f()方法和g()方法与父类Base方法同名,因此Derived的方法会覆盖Base的方法。在执行 Base base=new Derived(); 语句时,会调用Base类的构造函数,而在Base的构造函数中,执行了g()方法,由于Java语言的多态性,此时会调用子类Derived的g()方法,而不是父类Base 的g()方法,因此会输出"Derived g()".由于实际创建的是Derived对象,后面的方法调用都会调用子类Derived的方法。
但要注意,若此时父类中没有f()方法和g()方法,会编译报错。
示例二:
1 package Test; 2 3 public class Base { 4 private String baseName="base"; 5 public Base(){ 6 callName(); 7 } 8 9 public void callName(){ 10 System.out.println(baseName); 11 } 12 13 static class Sub extends Base{ 14 private String baseName="sub"; 15 public void callName(){ 16 System.out.println(baseName); 17 } 18 } 19 20 public static void main(String[] args) { 21 Base base=new Sub(); 22 } 23 }
程序运行结果:
在上面的例子中,new Sub();在创造派生类的过程中首先创建基类对象,然后才能创建派生类。创建基类即默认调用Base()方法,在方法中调用callName()方法,由于派生类中存在此方法,则被调用的callName()方法是派生类中的方法,此时派生类中普通成员变量(private String baseName="sub";)还未构造,所以变量baseName的值为null。
此外,只有类的方法才有多态的概念,类的成员变量没有多态的概念。示例如下:
1 public class Base { 2 public int i=1; 3 }
1 public class Derived extends Base{ 2 3 private int i=2; 4 5 public static void main(String[] args) { 6 Base base=new Derived(); 7 System.out.println(base.i); 8 } 9 }
程序运行结果:
由此可见,成员变量是无法实现多态的,类的成员变量的值取父类还是子类并不取决于创建对象的类型,而是取决于所定义变量的类型,这是在编译期间确定的。
以上是关于多态实现的机制的主要内容,如果未能解决你的问题,请参考以下文章