недостатки наследования в Java

Может любой объяснять недостаток наследования в Java

6
задан user252521 30 June 2010 в 14:59
поделиться

4 ответа

вы, вероятно, захотите прочитать:

Эффективная Java ™, второе издание Автор: Джошуа Блох

Глава 4. Классы и интерфейсы

Правило 16: Предпочитайте композицию наследованию

Правило 17: Дизайн и документация для наследования или иначе запрещайте его

Правило 18: Предпочитайте интерфейсы абстрактным классам

9
ответ дан 8 December 2019 в 12:18
поделиться

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

Конкретный пример:

Допустим, у вас есть класс, который управляет списком имен ...

public class MyNameManager {
  private List<String> numbers = new LinkedList<String>();

  public void add(String value) {
    numbers.add(value);
  }

  public void addAll(Collection<String> values) {
    for(String value : values) {
      add(value);
    }
  }

  public void remove(String value) { //... }

  //...
}

Теперь предположим, что вы хотите создать новый подкласс, который также подсчитывает общее количество раз, когда имя добавляется к list, например:

public class MyCountingNameManager extends MyNameManager {
  private int count = 0;

  @Override
  protected void addAll(Collection<String> values) {
    count += values.size();
    super.addAll(values);
  }

  @Override
  protected void add(String value) {
    count += 1;
    super.add(value);
  }
}

Выглядит довольно просто, не так ли? Но рассмотрим результат следующего:

MyCountingNameManager m = new MyCountingNameManager();
m.add("bob");
m.add("Sally");

Теперь счет 2, и все хорошо. Но если бы мы сделали следующее:

List<String> family = new List<String>();
family.add("mom");
family.add("dad");
family.add("brother");

MyCountingNameManager m = new MyCountingNameManager();
m.add(family);

Счетчик теперь равен 6, а не 3, как вы, вероятно, ожидали.Это связано с тем, что вызов addAll добавляет размер Коллекции значений (который равен 3) к счетчику, а затем вызывает метод super.addAll для выполнения фактической обработки. super.addAll выполняет итерацию Коллекции и вызывает метод add для каждого значения. Но поскольку мы работаем в MyCountingNameManager и , а не в a MyNameManager , переопределенный метод add в подклассе вызывается каждый раз . Выполняемый метод MyCountingNameManager.add также увеличивает счетчик! В результате каждое имя засчитывается дважды!

Я считаю, что этот пример взят из Effective Java. Вы обязательно должны найти копию и прочитать элементы, перечисленные в ответе Виле, для более глубокого понимания некоторых случаев, когда наследование не подходит.

3
ответ дан 8 December 2019 в 12:18
поделиться

Взять хотя бы статью Аллена Холуба в JavaWorld под названием Почему расширение - зло . Он обсуждает такие вещи, как сильная связь и проблема хрупкого базового класса .

5
ответ дан 8 December 2019 в 12:18
поделиться

Мы предпочитаем композицию наследованию, потому что, когда мы добавляем (в частности) или изменяем функциональность путем создания подклассов, мы присоединяем эту новую функциональность к классу - так что везде, где нам нужна новая функциональность, нам нужен этот класс. Это распространяется даже на другие подклассы - и с моделью одиночного наследования Java, если у нас есть два новых бита функциональности, которые мы хотим в еще одном классе, нет (простого) способа ввести оба бита, если каждый находится в отдельном подклассе изначальный предок.

Для сравнения: если мы расширяем функциональность посредством композиции, любой класс - в существующей иерархии или вне ее - может включить ее, просто включив крошечный класс, у которого есть новая функция. Это проще, чище, удобнее для повторного использования и легче читать.

Наследование имеет свое место, но оно не подходит для многих, многих профессий.

2
ответ дан 8 December 2019 в 12:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: