Java中的多态

这或许是最短小精干的多态文章了。

多态

优势

多态是是继抽象跟继承之后的第三个特征。多态不仅能够改善代码的组织结构和可读性,还能提高程序的可拓展性。 消除类型之间的耦合关系。

向上转型

把某个对象的引用视为基类的引用的做法称为向上转型。

绑定

方法调用绑定(前期绑定)

将一个方法调用一个与方法所在的类(方法体主体)关联起来被称为绑定。 若在程序执行前进行绑定,叫做前期绑定。

运行时绑定(后期绑定,动态绑定)

在运行的时候根据对象的类型进行绑定。

Java中除了static跟final,private方法,其他方法方法都是动态绑定。因为 static final方法是不可以被覆盖的,private 不能被继承只能被所在类所使用。

final 除了可以防止方法被覆盖,而且还可以有效关闭动态绑定。这样编译器就可以为 final 方法调用生成更有效的代码,但是这样对性能的提高并不是很明显。所以实际开发中,不要为了提高性能而执意将类型改成 final 。

PS:这两种绑定是编程语言的功能,前期绑定一般用于面向方法的编程语言使用,比如C,就只有一种前期绑定,而绑定绑定需要建立一种机制,从运行时判断需要调用哪个对象,也就是需要在对象中安置唯一的类型标识信息。

构造方法

调用顺序

基类的构造器在被导出类的构造过程中被调用,而且是按照继承逐层向上链接,以使每个基类的构造方法都能得到使用。编译器这样做的目的就是为了去确保基类能够被正确完整的构造,因为在基类构造方法可能会执行一些初始化数据。

清理顺序

如果需要执行清理动作,调用顺序是先从子类开始,然后再到基类。

构造器内部的多态

class Glyph {

  void draw() { print("Glyph.draw()"); }

  Glyph() {

    print("Glyph() before draw()");

    draw();//这里会使用子类的覆盖方法,但是这时候还没初始化完毕,所以子类的变量全部都是初始化数据。

    print("Glyph() after draw()");

  }

}   


class RoundGlyph extends Glyph {

  private int radius = 1;

  RoundGlyph(int r) {

    radius = r;

    print("RoundGlyph.RoundGlyph(), radius = " + radius);//这时候父类已经初始化完了,r 就有值了。

  }

  void draw() {

    print("RoundGlyph.draw(), radius = " + radius);

  }

}   


public class PolyConstructors {

  public static void main(String[] args) {

    new RoundGlyph(5);

  }


/* Output:

Glyph() before draw()

RoundGlyph.draw(), radius = 0

Glyph() after draw()

RoundGlyph.RoundGlyph(), radius = 5

*///:~

用尽最简单的方法使对象进入正常的状态。如果可以的话,避免调用其他方法。在构造器唯一能安全的调用那些方法是基类中的final方法。

协变返回类型

协变返回类型支持返回更具体的子类类型

用继承进行设计

选择组合优于继承。组合不会强制我们的程序进入继承的层次结构中,而且组合更加灵活,因为可以动态选择类型。相反,继承在编译的时候就需要确切的类型。

通用准则:用继承表达行为上的差异,并用字段表达状态上的变化。

  • 发表于 2017-11-14 15:24
  • 阅读 ( 1643 )
  • 分类:Java

0 条评论

请先 登录 后评论
不写代码的码农
MVP

男优

3 篇文章

作家榜 »

  1. 威猛的小站长 124 文章
  2. Jonny 65 文章
  3. 江南烟雨 36 文章
  4. - Nightmare 33 文章
  5. doublechina 31 文章
  6. HJ社区-肖峰 29 文章
  7. 伪摄影 22 文章
  8. Alan 14 文章