Извлечение "Суперкласса" или "Интерфейса"?Есть ли «эмпирическое правило»? - PullRequest
0 голосов
/ 23 января 2019

При определении одного и того же кода в разных классах, как мы решаем, следует ли нам извлечь его в интерфейс или в суперкласс? Поскольку интерфейсы не могут содержать никаких свойств, это просто сказать («правило большого пальца»):

Если для обоих классов есть общее свойство, мы извлекаем его в суперкласс, иначе в интерфейс?

Ситуация 1: У меня есть 2 отдельных класса с 1 идентичным именованным методом, скажем, CalcuCost (). -> Интерфейс

Ситуация 2: У меня есть 2 отдельных класса с 1 идентичным именованным методом, скажем, CalcuCost () и у нас есть идентификатор в виде строки. -> Суперкласс

Как мы решаем что делать?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Поток , предложенный автором @ jaco0646, хорошо объясняет разницу между суперклассами и интерфейсами.

Что касается «эмпирического правила», я обычно спрашиваю себя: отношения между абстракциями а ...

  • "ведут себя как" отношения?-> interface
  • "это" отношения?-> суперкласс

Мышление в этих терминах делает кодовую базу более легкой для понимания, более интуитивно понятной для навигации, чтения и обслуживания.

Также имейте в виду, что вы можете наследовать только от одного суперкласса,Наследование является сильным контрактом, который создает сильно связанные отношения, поэтому его следует использовать только тогда, когда этого требует ситуация (на мой взгляд, когда концептуальная модель хорошо согласуется с типом отношений «является»).

0 голосов
/ 23 января 2019

Несмотря на то, что это в основном мнение, вы должны помнить одну вещь:

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 {

}

Очевидно, что результат будет:

Parent: 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% уверены, что родительского класса нет,и никогда не будет одной (которая может обеспечить (или наследовать)) реализацию или сигнатуру этого метода?Тогда это свободный выбор.

С другой стороны, если вы выберете метод по умолчанию, и кто-то решит добавить родительский класс, это может привести к некоторой стрессовой отладке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...