这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战
本篇是记杂乱细节的第二篇,主要讲述继承与封装的相对关系、动态绑定的相关理解
继承与封装
首先,Java的三大特性 —— 封装、继承、多态
继承
继承是Java特性之一,是十分便利的一种编程思想,被广泛应用于Java API,框架和类库中,使用者可以利用继承,重写适当方法进行定制,就可以简单方便地实现强大的功能。并且继承遵从 is-a 的原则;也就是鸟作为父类,那么fly()这个方法就会作为所有继承子类的方法。
封装
封装也是Java特性之一,意义在于隐藏实现细节,提供简化接口,使调用者仅需调用方法,而无需知道实现的细节。
继承破坏封装
- 继承可能破坏封装,而封装可以说是程序设计的第一原则;另外,继承可能没有反映出is-a关系。(例如企鹅也是鸟类,但是并不能具备fly()方法)
- 某种意义上,Java的封装掩盖了细节的实现,这也就是接口和private 的意义;
- 然而继承的意义在于Java的动态绑定,在于最初设计的对象理念is-a;
- 相互冲突之下,继承会使封装的细节暴露;并且需要互不干扰
动态绑定
简单举个例子 父类
public class Base{
private int count;
private static final int MAX_VALUE = 1000;
private int[] arr = new int[MAX_VALUE];
public void add(int num){
if(count < MAX_VALUE){
arr[count++] = num;
}
}
public void addAll(int[] num){
for(int i : num){
add(i);
}
}
}
子类
public class Child extend Base{
private long sum;
@Override
public void add(int num){
super.add(num);
sum+=num;
}
@Override
public void addAll(int[] num){
super.addAll(num);
for(int i = 0 ;i<num.length;i++){
sum+=num[i];
}
}
}
public long getSum(){
return sum;
}
public static void main(String[] args){
Child c = new Child();
c.addAll(new int[]{1,2,3});
System.out.println(c.getSun());
}
动态绑定的原因,导致继承的方法会从子类一直寻找 上去,如果子类找不到才会往父类查找。当前的方法,super.addAll方法, 父类的addAIl方法调用了 add方法,找到子类的add方法,子类再super.add方法。导致add 了两次。
总结
子类与父类的实现细节总是相互依赖的,子类拓展父类功能,不止需要知道父类能做什么,更要知道实现的逻辑;父类也不能随意改动逻辑,否则可能引起子类雪崩