Чому рамки Windows Forms / Swing надають перевагу спадкуванню замість складу?


12

Сьогодні мій професор прокоментував, що йому здається дивним, що, хоча філософія SWT полягає в тому, щоб зробити свій власний контроль за складом, Swing, здається, підтримує спадщину.

Я майже не контактую з обома рамками, але, з того, що я пам’ятаю, у C # у Windows Forms зазвичай розширюються елементи управління, як і Swing.

Оскільки люди, як правило, віддають перевагу композиції над спадщиною, чому люди Swing / Windows Forms не віддають перевагу композиції замість спадкування?


2
Багато що змінилося за 15-20 років тих API-програм! Двигуни візуалізації не мали чарівного XML-клею, який би прив'язував об'єкти екрана до екземплярів будь-якого довільного конкретного класу "назад у той день";)

1
Більшість кодів Swing, які я бачу, використовує розширення за складом. Я не впевнений, де твій професор бере свої дані.

Я сам бачив багато розмаху в мережі з успадкуванням замість композиції - хоча в основному навчальні посібники. але справді форми Windows використовуються майже виключно у спадок!
пожирав елізіум

Відповіді:


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 насправді розроблена у відповідності зі складеною схемою дизайну. Зазначимо, що там багато спадщини, але зазвичай ви складете власні форми, використовуючи композицію. Тобто форма - це композиція проміжних контейнерів та елементів управління.


"Тобто форма - це композиція проміжних контейнерів та елементів управління". Звичайно. Але зазвичай я бачу, що коли люди хочуть створити своє власне вікно (або все, що називається в Swing), вони успадкують від класу вікон замість композиції.
пожирав елізіум

@devoured elysium Це правда. Але для створення форми вони використали б композицію. Тож це трохи спадщини та багато складу.

@ почитав, я думаю, що це випадки, коли люди не розуміють, що підручник, який вони використовують, не відповідає кращій практиці, оскільки це сприяє стислість.
Пітер Тейлор

1

З Явою набагато простіше в кінцевому підсумку використовувати спадщину лише тому, що все віртуально. Потрібно виправити "функцію" в JTable / JFrame? Розгорніть його, замініть проблемні методи, а потім використовуйте свою таблицю / рамку всюди.

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


Що ви маєте на увазі під "все віртуально "?
Йонас

у Java кожен метод неявно віртуальний (може бути переосмислений). У C # ви маєте чітко оголосити метод як virtual, а щоб перекрити його, ви явно оголосите його як override. У java ви можете переосмислити все, що бачите, і ви можете збільшити його видимість у підкласі (ви можете оприлюднити захищені методи у підкласі!)
Джон Гарднер,

Зауважте, що ви не можете замінити finalметод на Java, навіть якщо сам базовий клас не є final.
перп

це правда @perp. але в Java вам доведеться вийти зі свого шляху (додавши остаточний), щоб не допустити віртуального. C # - навпаки, ви повинні вийти зі свого шляху, щоб бути віртуальним. І дуже невеликий відсоток від стандартного часу виконання Java вважається остаточним.
Джон Гарднер

1

В блоці Ефективна Java , пункт 17, Блох зазначає, що клас, призначений для успадкування, "повинен документувати своє самозастосування методів, що перезаписуються". Ознакою цього є фраза цієї реалізації . Ви побачите це на класах як JTableі JInternalFrame. Це одна міра успадкування за дизайном у Swing.


-2

З C # 3.5 у нас є концепція, що називається Методами розширення, яка дозволяє концепцію композиції, ніж успадкування.

У цьому процесі ми реалізуємо розширену функціональність до існуючого класу, просто додаючи клас розширення, який надає нову функцію існуючому класу.

Ви можете посилатися тут для отримання більш детальної інформації


Я не бачу доречності для створення нових класів управління WinForms. Не могли б ви детальніше?
Пітер Тейлор

@Peter: Це не стосується лише класів Windows форм. Це може бути застосоване і з нашого коду. Ви можете розширити будь-який із наявних класів, просто додавши статичний клас, а потім додавши новий метод з 1-го аргументу, як це, щоб базовий об'єкт можна було зв'язати. Після складання коду ви отримуєте щойно доданий метод як метод самого базового класу. Ось що стверджує склад. сподіваюся, що я маю рацію ..
Сараванан

1
Я знаю, що таке методи розширення, і часом вони досить зручні, але це питання стосується різних підходів до створення нових класів.
Пітер Тейлор

@Peter: Тоді я можу лише вказати на використання лише часткових класів, крім того, наскільки я розумію, C # не має жодної іншої чудової функції. Якщо ви знаєте що-небудь, будь ласка, повідомте мене про це.
Сараванан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.