Почему платформы Windows Forms / Swing предпочитают наследование, а не композицию?

12

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

У меня почти нет контакта с обеими платформами, но из того, что я помню в Windows Forms C #, обычно расширяют элементы управления, как Swing.

Поскольку люди обычно предпочитают композицию наследованию, почему люди Swing / Windows Forms не предпочитают композицию вместо наследования?

пожрал Элизиум
источник
2
Многое изменилось за 15-20 лет существования этих API! У движков рендеринга не было волшебного клея XML для привязки экранных объектов к экземплярам любого произвольного конкретного класса «назад в день»;)
1
Большая часть кода Swing, который я вижу, использует расширение по составу. Я не уверен, где твой проф получает свои данные.
Я сам видел много различий в сети с наследованием, а не с композицией - в основном это учебники. но формы окон действительно используются на основе почти исключительно наследования!
пожрала Элизиум

Ответы:

7

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

class MyComponent implements JComponent {
    JPanel panel;
    public boolean contains(int x, int y) {
        return panel.contains(x, y);
    }
    ...
}

Есть также причина эффективности, чтобы предпочесть наследование, а не композицию - переопределение ничего не стоит (при условии отсутствия superвызова), в то время как составление стоит доплаты INVOKEVIRTUAL. Я не знаю, повлияло ли это на дизайн Swing, но это большая проблема для коллекционных классов.

Даниэль Любаров
источник
2

Swing Framework фактически разработан в соответствии с Composite Design Pattern. Конечно, там много наследства, но вы обычно составляете свои собственные формы, используя композицию. То есть форма представляет собой композицию контейнеров промежуточного уровня и элементов управления.

Винсент Рамдани
источник
«То есть форма - это композиция контейнеров и элементов управления промежуточного уровня». Конечно. Но обычно я вижу, что когда люди хотят создать свое собственное окно (или как это называется в Swing), они наследуют от класса окна вместо использования композиции.
пожрала Элизиум
@ Deoured Elysium Это правда. Но для создания формы они использовали бы композицию. Так что это немного наследства и много композиции.
@ devoured, я думаю, что это тот случай, когда люди не понимают, что учебник, который они используют, не следует передовой практике, потому что он способствует краткости.
Питер Тейлор
1

С Java намного проще использовать наследование только потому, что все виртуально. Нужно исправить "функцию" в JTable / JFrame? Расширьте его, переопределите методы задачи, а затем используйте всю свою таблицу / фрейм.

Я думаю, что с такими вещами, как WPF, где привязка данных является основной особенностью проекта, значительно упрощается создание композиции вместо наследования.

Джон Гарднер
источник
Что вы имеете в виду под "все виртуально "?
Джонас
в Java каждый метод неявно виртуален (может быть переопределен). В C # вы должны явно объявить метод как virtualи переопределить его, вы явно объявите его как override. В java вы можете переопределить все, что видите, и увеличить его видимость в подклассе (вы можете сделать защищенные методы публичными в подклассе!)
Джон Гарднер,
Обратите внимание, что вы не можете переопределить finalметод в Java, даже если сам базовый класс - нет final.
преступник
это правда @perp. но в Java вы должны выйти из своего пути (добавив окончательный вариант), чтобы предотвратить виртуальный. C # - это обратный путь, вы должны идти своим путем, чтобы быть виртуальным. И очень маленький процент от стандартного времени выполнения Java отмечен как финальный.
Джон Гарднер
1

В статье 17 « Эффективная Java» Блох упоминает, что класс, предназначенный для наследования, «должен документировать свое самостоятельное использование переопределяемых методов». Отличительной чертой этой фразы является эта реализация . Вы увидите это в классах как JTableи JInternalFrame. Это одна мера наследования по дизайну в Swing.

trashgod
источник
-2

Начиная с C # 3.5, у нас есть понятие, называемое «Методы расширения», которое допускает концепцию композиции, а не наследования.

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

Вы можете обратиться сюда для более подробной информации

Saravanan
источник
Я не вижу смысла в создании новых классов управления WinForms. Не могли бы вы уточнить?
Питер Тейлор
@Peter: Это не относится только к классам форм Windows. Это может быть применимо и из нашего кода. Вы можете расширить любой существующий класс, просто добавив статический класс, а затем добавив новый метод с 1-м аргументом, как этот, чтобы базовый объект мог быть связан с. После того, как вы скомпилируете код, вы получите новый добавленный метод как метод самого базового класса. Это то, что говорится в композиции. надеюсь, что я прав ..
Сараванан
1
Я знаю, что такое методы расширения, и они иногда очень удобны, но этот вопрос касается разных подходов к созданию новых классов.
Питер Тейлор
@Peter: Тогда я могу лишь указать на использование только частичных классов, кроме того, насколько я понимаю, C # не имеет никаких других замечательных особенностей. Если вы знаете, пожалуйста, дайте мне знать.
Сараванан