面向对象三大特征:封装、继承、多态;
封装:1 特征和行为共同组成对象,以对象为单位进行操作;
2 访问控制权限,保证对象的“私有化”,分离实现和接口;
继承:实现相似对象的共性抽取;(继承和组合是实现复用类的两种方式)
多态:狭义:方法的重载/重写,造型方式。(多态表现在普通方法的差异性上,变量和static,final都不能表现多态)
广义:为消除类型之间耦合关系,一种类型可以表现出和其相似类型的区别;
1 多态实现
1.1 绑定方式
将方法的调用和方法的实体关联起来成为“绑定”;
前期绑定(编译期绑定):在程序执行前进行绑定,一般由编译期和连接程序实现。
后期绑定(运行期绑定):程序运行期间根据对象类型进行绑定。
Java中除了final(private方法属于final方法)方法和static方法之外,都是后期绑定。
例如:
“点出什么看引用,调用什么看对象”。一个子类对象可以和一个父类引用进行关联,称之为向上造型。当使用父类引用的时候(编写期间),能够显示的方法和属性都是父类自身的(编译期绑定);当运行程序的时候,调用的却是子类重写的方法(属性不予显现),此时是运行期绑定。
缺点:很明显,向上造型会让子类失去扩展的特征和行为,所以java相对应地可以进行“向下造型”。
1.2 可扩展性
多态可以实现“将改变的事物和未改变的事物分离开来”。
例子:乐器类是笛乐器、管弦乐器、敲击乐器、铜管乐器的父类,笛乐器又是木笛乐器的父类。每个类都有自己的演奏方法play();多态可以搭配向上造型实现统一的music(乐器类){乐器类.play()}方法,传入的乐器类可以调用其具体对象(子类)的重写方法play(),达到一个演奏方法,多种声乐表现的形式。这种形式就是多态。
同时,乐器类和music(乐器类)方法可以保持不变,乐器类的子类却可以无限扩展,只要覆盖父类的play方法,都可以被music调用。这就是扩展性。
1.3 缺陷
1、覆盖私有方法:重写和重载只能应用于非私有方法上,覆盖私有方法,程序后期绑定无效,程序认为被覆盖的父类私有方法和子类的重写方法虽然同名,但是两种不同的方法。
2、域和静态方法:任何域(变量)访问操作都是编译器解析的,不是多态的。静态方法无法覆盖。
2 构造器和多态
2.1 构造器构造顺序
按声明顺序父类成员初始化->父类构造器->子类成员初始化->子类构造器->根据继承的顺序向下依次进行
2.2 继承与清理
当存在一些清理操作必须实现的时候,而要实现清理的对象被共享给了多个对象,需要按照子类->父类的顺序不断调用super.清理()方法;
2.3 构造器内部多态方法的行为
例子:父类构造器中调用了子类重写的方法。此时便会出现逻辑上的矛盾。
结果:程序会选择调用子类重写的方法。因为成员变量不具有多态性,所以若父类构造器中若使用了子类的成员变量,则输出为默认的0或null。
初始化过程中,首先会为要创建的对象以及对象继承的父类创建空间,并将存储空间清零(0或null),然后才会执行2.1的构造顺序。
3 用继承设计
“is-a”:纯继承,子类不进行扩展。
“like-a”:子类进行扩展。
准则:
继承表达行为间的差异;字段表达状态上的变化。
字段可以是任何承载状态的变量(包括对象)。将事物的行为和状态进行分离。
4 总结
多态意味着“不同的形式”,是一种不能单独来看待的特性,需要和其他特性协同工作。