Java提供了编译时多态和运行时多态两种多态机制。前者是通过方法重载实现的,后者是通过方法的覆盖实现的。

  在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式。

  在Java语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类中的实例对象。同样,接口中的引用变量也可以指向其实现类的实例对象。而程序调用的方法在运行时期才动态绑定(绑定是指将一个方法调用和一个方法主体联系在一起),绑定的是引用变量所指向的具体实例对象的方法,也就是内存中正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。通过这种动态绑定实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法覆盖实现的多态也可以被称为运行时多态。

  

  示例一:

 public class Base {
public Base(){
g();
} public void g() {
System.out.println("Base g()");
} public void f() {
System.out.println("Base f()");
}
}
 public class Derived extends Base{

     public void g() {
System.out.println("Derived g()");
} public void f() {
System.out.println("Derived f()");
} public static void main(String[] args) {
Base base=new Derived();
base.f();
base.g();
}
}

  程序运行结果:

          

  在上面的例子中,由于子类Derived的f()方法和g()方法与父类Base方法同名,因此Derived的方法会覆盖Base的方法。在执行  Base base=new Derived();  语句时,会调用Base类的构造函数,而在Base的构造函数中,执行了g()方法,由于Java语言的多态性,此时会调用子类Derived的g()方法,而不是父类Base 的g()方法,因此会输出"Derived g()".由于实际创建的是Derived对象,后面的方法调用都会调用子类Derived的方法。

  但要注意,若此时父类中没有f()方法和g()方法,会编译报错。

  示例二:

 package Test;

 public class Base {
private String baseName="base";
public Base(){
callName();
} public void callName(){
System.out.println(baseName);
} static class Sub extends Base{
private String baseName="sub";
public void callName(){
System.out.println(baseName);
}
} public static void main(String[] args) {
Base base=new Sub();
}
}

  程序运行结果:

        

  在上面的例子中,new Sub();在创造派生类的过程中首先创建基类对象,然后才能创建派生类。创建基类即默认调用Base()方法,在方法中调用callName()方法,由于派生类中存在此方法,则被调用的callName()方法是派生类中的方法,此时派生类中普通成员变量(private String baseName="sub";)还未构造,所以变量baseName的值为null。

  此外,只有类的方法才有多态的概念,类的成员变量没有多态的概念。示例如下:

 public class Base {
public int i=1;
}
 public class Derived extends Base{

     private int i=2;

     public static void main(String[] args) {
Base base=new Derived();
System.out.println(base.i);
}
}

  程序运行结果:

         

  由此可见,成员变量是无法实现多态的,类的成员变量的值取父类还是子类并不取决于创建对象的类型,而是取决于所定义变量的类型,这是在编译期间确定的。

最新文章

  1. 浅谈WEB跨域的实现(前端向)
  2. .net 模拟登录Post提交
  3. (转)分布式深度学习系统构建 简介 Distributed Deep Learning
  4. Ubuntu下如何将普通用户提升到root权限
  5. 是否可以继承String类?
  6. jquery编写插件
  7. LINUX常用命令--重定向、管道篇(四)
  8. 第二次冲刺spring会议(第五次会议)
  9. MySql单表最大8000W+ 之数据库遇瓶颈记
  10. Android Studio JNI javah遇到的问题
  11. python模拟蒙特·卡罗法计算圆周率
  12. Luogu 3371【模板】单源最短路径
  13. python2用pip进行安装时报错Fatalerrorinlauncher:Unabletocreateprocessusing"
  14. [Swift]LeetCode641. 设计循环双端队列 | Design Circular Deque
  15. [转]安装v2ray,部署手机电脑***
  16. 王之泰201771010131《面向对象程序设计(java)》第十七周学习总结
  17. 一个request引发的bug
  18. jquery $('#form1').serialize()序列化提交表单
  19. 剑指Offer 46. 孩子们的游戏(圆圈中最后剩下的数) (其他)
  20. photoshop使用笔记-制作古代印章

热门文章

  1. 吴裕雄--天生自然 JAVA开发学习:网络编程
  2. scala slick mysql utf8mb4 支持
  3. 数论入门——斐蜀定理与拓展欧几里得算法
  4. 71)PHP,使用cookie的语法问题
  5. 吴裕雄--天生自然python学习笔记:抓取网络公开数据
  6. C++ 中类的内存布局
  7. git 代理配置方式
  8. G1最佳实践
  9. Qt QString 与 QByteArray 的转换
  10. notepad++下载及安装