- “封装”通过合并特征和行为来创建新的数据类型;
- “实现隐藏”通过将细节“私有化”把接口和实现分离开来;
- “多态”消除类型之间的耦合关系(多态也称为动态绑定、后期绑定或运行时绑定);
再说 final
Java 中除了 static 方法和 final 方法(private 方法属于 final 方法)之外,其他所有的方法都是后期绑定。也就是说,final 可以“关闭”动态绑定。
多态缺陷一:“覆盖”私有方法
如果子类覆盖了父类的私有方法(其实准确来说并不是覆盖,因为私有方法不会被覆盖,这里说的只是方法签名一致罢了),新创建的子类实例向上转型成父类对象后,再调用该方法,则最终调用的是父类的私有方法,而不是子类的相同签名的方法。
多态缺陷二:域与静态方法
在代码里直接访问某个域(即直接通过实例访问其值属性,而不是通过 getter/setter),那么这个访问就是在编译期进行解析。这样就会导致,如果你把子类向上转型为了父类,然后再直接访问其值属性,那么访问到的就是父类里面的值属性(前提是子类和父类同时拥有一个变量名相同但值不同的值属性)。
如果子类覆盖了父类的静态方法,然后子类实例向上转型为父类时,再调用该静态方法,则最终使用的是父类的静态方法。
构造器和多态
构造器不同于其他种类的方法,实际上它们是隐式的静态方法,所以它们并不具有多态性。
协变返回类型
啥是协变返回类型?其实很简单,就是子类在覆盖父类的方法时,子类中的方法可以返回父类方法返回类型的子类型,也就是更具体的类型,这一点也符合多态的规则。