多态

在面向对象的程序设计语言中,多态是继数据抽象和继承后的第三个基本特征.

多态通过分离做什么和怎么做,从另一个角度将接口和实现分离开来.

多态允许同一份代码可以毫无差别的运行在不同类型上.

多态的实现

java编译器只拥有一个基类引用,他如何知道调用的是哪个子类的方法呢.

解决方法就是后期绑定.运行时根据对象类型进行绑定.

Java中除了static和final方法,其他方法都会默认后期绑定,

可扩展性

一个设计良好的oop程序中,大多数方法都应该遵循方法只与基类接口通信,这样就保证了程序是可扩展的.

缺陷

  • 覆盖私有方法.因为私有方法默认为final,在子类中不可见也不可被覆盖,所以当子类方法与父类私有方法签名相同的时候,父类引用无法调用子类的覆盖方法
  • 域与静态方法:静态方法和域无法多态运行,因为静态方法与类绑定而非具体对象,域操作会被编译器解析,所以不是多态的

构造器和多态

因为构造器时隐式static的,所以也不是多态的.

构造器的调用过程:基类的构造器总是在子类构造器过程被调用,而且会递归的调用到最顶层的基类.因为只有基类的构造器才有能力对基类的元素进行初始化,因此必须调用.

如果没有显式的调用,编译器会默认调用基类无参数默认构造器,如果没有调用且基类没有默认构造器将会报错.

继承与清理:

如果对象有清理需求,可以自己自定义清理方法,但是随后的导出类都必须在清理方法中调用基类清理方法,只有基类的清理方法可以执行基类的清理动作.

如果多个对象需要共享子对象,则对子对象的清理需要引入引用计数.

构造器内部的多态方法行为.

因为在构造器内部调用多态方法,可能会调用到导出类的方法,而此时导出类并未初始化,因此程序会产生不可预知的结果

因此在编写构造器的时候有一个准则:尽可能简单的使对象初始化完成,避免调用其他方法.在构造器内部唯一可以安全调用的方法是基类的private 和final方法 ,因为他们默认不可被继承,不是多态,不会产生上述问题.

协变返回类型

Java se5添加了协变返回类型,允许导出类被覆盖方法可以返回基类返回类型的某种导出类型.

用继承进行设计

一般应该优先使用组合,因为组合不会强制我们的程序设计进入继承的层次结构中,更加灵活.

组合的灵活还表现在它可以动态选择类型(在类中的引用可以选择不同的导出类)

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

纯继承与扩展

纯继承表示子类的接口和基类完全相同,而扩展表示子类会有基类没有的方法.

向下转型与运行时类型识别

(RTTI)运行时类型识别,java语言中,所有的类型转换都会被检查,只有类型转换合适时会转换成功,如果不的话会抛出ClassCastException





原文地址:https://www.cnblogs.com/renluxiang/p/13bc59aefc51c59fda615973cd7d5b93.html