Java多态的实现机制
2017-05-02 07:34
288 查看
多态是面向对象程序设计中代码重用的一个重要机制,它表示当同一个操作作用在不同对象时,会有不同的语义,从而产生不同的结果,例如,同样是执行“+”操作,“3+4”用来实现整数相加,而“3”+“4”却实现了字符串的连接。在Java语言中多态主要有以下两种表现方式:
1)方法的重载(overload)。重载是指同一个类中有多个同名的方法,但它们有着不同的参数,因此在编译时就可以确定到底调用哪个方法,它是一种编译时多态。重载可以被看做一个类中的方法多态性。
2)方法的覆盖(override)。子类可以覆盖父类的方法,因此同样的方法会在父类与子类中有着不同的表现形式。在Java语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类的实例对象(也就是子类也是父类的一种)。同样,接口中的引用变量,也可以指向其实现类的实例对象(Spring框架中使用注解注入bean时,经常这么用)。而程序调用的方法在运行期才动态绑定(绑定是指将一个方法调用和一个方法主体连接到一起),就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量类型中定义的方法。通过这种动态绑定的方法,实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法覆盖实现的多态也可以被称为运行时多态,示例如下:
Derived g()
Derived f()
Derived g()
上例中,由于子类Derived的f()方法和g()方法与父类Base的方法同名,因此Derived的方法会覆盖Base的方法。在执行Base b = new Derived()语句时,会调用Base类的构造函数,而在Base()的构造函数中,执行了g()方法,由于Java语言多态特性,此时会调用子类Derived的g()方法,而非父类Base的g()方法,因此会输出Derived g()。由于实际创建的是Derived类的对象,后面的方法调用都会调用子类Derived的方法。
此外,只有类中的方法才有多态的概念,类中成员变量没有多态的概念,示例如下:
输出结果:
1
由此可见,成员变量是无法实现多态的,成员变量的值取父类还是子类并不取决于创建对象的类型(即不取决于调用了谁的构造函数),而是取决于所定义的类型,这是在编译器确定的。在上例中,由于base所属的类型为Base,b.i指的是Base类中定义的i,因此程序输出的结果为1。
1)方法的重载(overload)。重载是指同一个类中有多个同名的方法,但它们有着不同的参数,因此在编译时就可以确定到底调用哪个方法,它是一种编译时多态。重载可以被看做一个类中的方法多态性。
2)方法的覆盖(override)。子类可以覆盖父类的方法,因此同样的方法会在父类与子类中有着不同的表现形式。在Java语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类的实例对象(也就是子类也是父类的一种)。同样,接口中的引用变量,也可以指向其实现类的实例对象(Spring框架中使用注解注入bean时,经常这么用)。而程序调用的方法在运行期才动态绑定(绑定是指将一个方法调用和一个方法主体连接到一起),就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量类型中定义的方法。通过这种动态绑定的方法,实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法覆盖实现的多态也可以被称为运行时多态,示例如下:
package com.js; /** * 多态例子 * @author Noah * */ class Base{ public Base(){ g(); } public void f(){ System.out.println("Base f()"); } public void g(){ System.out.println("Base g()"); } } class Derived extends Base{ public void f(){ System.out.println("Derived f()"); } public void g(){ System.out.println("Derived g()"); } } public class Test{ public static void main(String[] args){ Base base = new Derived(); base.f(); base.g(); } }输出结果:
Derived g()
Derived f()
Derived g()
上例中,由于子类Derived的f()方法和g()方法与父类Base的方法同名,因此Derived的方法会覆盖Base的方法。在执行Base b = new Derived()语句时,会调用Base类的构造函数,而在Base()的构造函数中,执行了g()方法,由于Java语言多态特性,此时会调用子类Derived的g()方法,而非父类Base的g()方法,因此会输出Derived g()。由于实际创建的是Derived类的对象,后面的方法调用都会调用子类Derived的方法。
此外,只有类中的方法才有多态的概念,类中成员变量没有多态的概念,示例如下:
package com.js; /** * 成员变量没有多态的概念 * @author Noah * */ class Base{ public int i = 1; } class Derived extends Base{ public int i = 2; } public class Test{ public static void main(String[] args){ Base base = new Derived(); System.out.println(base.i); } }
输出结果:
1
由此可见,成员变量是无法实现多态的,成员变量的值取父类还是子类并不取决于创建对象的类型(即不取决于调用了谁的构造函数),而是取决于所定义的类型,这是在编译器确定的。在上例中,由于base所属的类型为Base,b.i指的是Base类中定义的i,因此程序输出的结果为1。
相关文章推荐
- java 笔试 :java中实现多态的机制是什么
- Java中多态的实现机制
- Java中多态的实现机制
- java中实现多态的机制是什么?
- java中实现多态的机制是什么?
- Java中多态的实现机制
- Java多态实现机制
- 【JAVA基础小问题】java中实现多态的机制是什么?
- Java中实现多态的机制是什么
- 深入java (类)对象初始化,类构造函数的调用以及多态(java中多态的实现机制以后补充)
- java多态的实现机制
- java中实现多态的机制是什么?
- Java中多态的实现机制
- 深入Java核心 Java中多态的实现机制(1)
- java中实现多态的机制是什么?
- Java中多态的实现机制
- Java中多态的实现机制
- java c++ 实现多态(polymorphism)的机制
- java中方法的覆盖(多态实现的机制之一)
- Java 多态:动态绑定 及 内部实现机制