美文网首页
程序员修炼之道31-继承税

程序员修炼之道31-继承税

作者: DZQANN | 来源:发表于2022-02-22 22:28 被阅读0次

复合优于继承

这句话是Effective Java中非常经典的一句话。继承就是子类和父类之间的耦合,子类依赖了父类的实现,打破了封装性。

很多时候写代码使用继承是为了把Common的方法都放到基类中

public class BaseClass{
  protected void method1() {
    
  }
  
  protected void method2() {
    
  }
}

public class ClassA extends BaseClass {
  public void method3() {
    super.method()1;
    ......
  }
}

这种情况下是最没有必要的继承关系,应该将BaseClass变成一个一个Service,ClassA里面的方法调用Service内的方法,这样就弱化了依赖关系

Effective Java中举了一个非常好的例子。一个人想要自己写一个Set类,统计Set里面元素的个数,用了继承的方式

public class MySet<T> extents HashSet<T> {
  
  private int totalCount;
  
  @Override
  public boolean add(T element) {
    this.totalCount +=1;
    return super.add(element);
  }
  
  @Override
  public boolean addAll(Collection<T> elements) {
    this.totalCount += elements.size();
    return super().addAll(elements);
  }
  
}

这个时候如果调用addAll方法,添加3个元素,最后totalCount会是6。因为HashSet的addAll循环调用了add方法。

而如果是组合关系就不会有这个问题,将HashSet实例作为MySet的成员变量就好了。

可以使用继承的情形

1. 模板方法

这是一种设计模式,使用下来在一些小范围中还是比较方便的

public abstract class BaseClass {
  public void do() {
    step1();
    step2();
    step3();
  }
  
  private void step1() {
    
  }
  
  private void step3() {
    
  }
  
  protected void abstract step2();
}

public class ClassA extends BaseClass{
  @Override
  public void step2() {
    
  }
}

在实际开发中,因为继承的引用也有负面影响。比如有一次我需要在中间再加一步,有些子类需要实现,有些不需要,为了减少影响我只能让新加的步骤不是抽象方法,谁要用它就在子类中覆盖。一个还好,多个这种方法,继承结构就会越来越乱。

2. 为了继承而设计的类

今天刚刚碰到的一个例子,系统中所有的DB Entity都会有的字段是oid, version, create_by, last_update_by等等。那对应的,Entity对应的Vo就可以是一个基类,里面包含了所有common的字段,不用的vo就继承这个类,扩展自己特有的字段

3.真实存在的继承关系

比如系统中的地理信息。有行政区划、国家、省、市、区等。在真实中,国家、省、市等就是包含在行政区划下面的,这时候就可以是继承关系,他们都有一些共同的动作,比如告诉外部我是属于哪个洲的行政区划。

最后结论其实还是,能不用继承就不要用继承

相关文章

网友评论

      本文标题:程序员修炼之道31-继承税

      本文链接:https://www.haomeiwen.com/subject/gzualrtx.html