提取“超类”或“接口”?有“经验法则”吗?

时间:2019-01-23 07:02:43

标签: java design-patterns interface superclass

当在不同的类中标识相同的代码时,我们如何确定应该将其提取到接口还是超类中?因为接口不能容纳任何属性,所以可以这样说(“经验法则”):

如果两个类都有一个公共属性,我们将其提取到超类中,否则将其提取到接口中?

情况1: 我有2个单独的类,具有1个相同的命名方法,例如:calculateCost()。 ->界面

情况2: 我有2个单独的类,具有1个相同的命名方法,例如:calculateCost()和 我们有id作为一个字符串。 ->超类

我们如何决定做什么?

2 个答案:

答案 0 :(得分:0)

即使这主要是意见,但您应该记住一件事:

public class Child extends Parent implements MyInterface {
  public static void main(String[] args) {
    Child c = new Child();
    c.logSomething("toLog");
  }
}

让我们检查所有可能的情况: 首先,在Parent类中而不是在接口中有这样一种方法。

public class Parent {
  public void logSomething(String toLog) {
    System.out.println("Parent: " + toLog);
  }
}

public interface MyInterface {

}

显然,结果将是:

  

父母:toLog

第二种情况,代码是由接口而不是类提供的。

public class Parent {

}

public interface MyInterface {
  default void logSomething(String toLog) {
    System.out.println("Interface: " + toLog);
  }
}

在这里,它也将起作用,结果将是:

  

接口:toLog

但是,当两者都提供时:

public class Parent {

  public void logSomething(String toLog) {
     System.out.println("Parent: " + toLog);
  }

}

public interface MyInterface {
  default void logSomething(String toLog) {
    System.out.println("Interface: " + toLog);
  }
}

结果将是:

  

父母:toLog

您是否100%确定没有父类,并且永远不会有(可能提供(或继承自身的))实现f或方法签名?然后,这是一个自由选择。

另一方面,如果您选择默认方法,但确实有人决定添加父类,则可能会导致一些压力大的调试。

答案 1 :(得分:0)

@ jaco0646的suggested thread很好地解释了超类和接口之间的区别。

至于“经验法则”,我通常会问自己:抽象之间的关系是...吗?

  • “喜欢”关系吗? ->界面
  • “是”关系吗? ->超类

这些术语的思想使代码库更易于理解,更易于导航,阅读和维护。

还请记住,您只能从一个超类继承。继承是一个强大的契约,可创建高度耦合的关系,因此仅应在情况需要时使用(我认为,当概念模型非常适合“是”一种关系时)。