实战小知识----02.06----Java杂谈(二)

85 阅读2分钟

这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

本篇是记杂乱细节的第二篇,主要讲述继承与封装的相对关系、动态绑定的相关理解

继承与封装

首先,Java的三大特性 —— 封装、继承、多态

继承

继承是Java特性之一,是十分便利的一种编程思想,被广泛应用于Java API,框架和类库中,使用者可以利用继承,重写适当方法进行定制,就可以简单方便地实现强大的功能。并且继承遵从 is-a 的原则;也就是鸟作为父类,那么fly()这个方法就会作为所有继承子类的方法。

封装

封装也是Java特性之一,意义在于隐藏实现细节,提供简化接口,使调用者仅需调用方法,而无需知道实现的细节。

继承破坏封装

  1. 继承可能破坏封装,而封装可以说是程序设计的第一原则;另外,继承可能没有反映出is-a关系。(例如企鹅也是鸟类,但是并不能具备fly()方法)
  2. 某种意义上,Java的封装掩盖了细节的实现,这也就是接口和private 的意义;
  3. 然而继承的意义在于Java的动态绑定,在于最初设计的对象理念is-a;
  4. 相互冲突之下,继承会使封装的细节暴露;并且需要互不干扰

动态绑定

简单举个例子 父类

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 了两次。

总结

子类与父类的实现细节总是相互依赖的,子类拓展父类功能,不止需要知道父类能做什么,更要知道实现的逻辑;父类也不能随意改动逻辑,否则可能引起子类雪崩