Як проектування на спадщину може спричинити додаткові витрати? [зачинено]


12

Так що я хотів наслідувати від sealed classв CSharp і погорів. Просто немає способу розкрити його, якщо у вас немає доступу до джерела.

Тоді це змусило мене задуматися "чому sealedнавіть існує?". 4 місяці тому. Я не міг цього зрозуміти, незважаючи на те, що читав про нього багато речей, таких як:

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

Нарешті, після багато роздумів, я вирішив сильно відредагувати оригінальне запитання на основі нової назви.

Старий питання був занадто широким і суб'єктивним. В основному це було питання:

  1. У старому заголовку: Одна вагома причина використовувати герметичну
  2. В тілі: Як правильно змінити герметичний клас? Забули про спадщину? Використовувати склад?

Але тепер, зрозумівши (чого я не робив вчора), що все sealedце - це запобігання успадкування , і ми можемо і повинні дійсно використовувати склад над спадщиною , я зрозумів, що мені потрібно - це практичні приклади.

Напевно, моє запитання тут (а насправді завжди було) саме те, що містер Міндор запропонував мені в чаті : Як проектування на спадщину може спричинити додаткові витрати?


5
Питання сформульовано досить агресивно і звучить як зухвала. Ви повинні переробити це, якщо хочете відповідні та об'єктивні відповіді.
Ейфорія

11
Дивіться, чому так багато запечатано рамкових класів? Ерік Ліпперт. Він надає кілька вагомих причин для запечатування класів.
Роберт Харві

9
Тоді ви не читали статті. Поверніться і прочитайте її ще раз. Це зводиться до цього: ви не можете передбачити незліченних способів, як клієнт може зламати ваш клас, розширивши його. Ви можете звинувачувати своїх клієнтів у цьому, але ви повинні підтримувати їх.
Роберт Харві

4
@Cawas Він міг, або ви можете прочитати статтю, яку він пов’язав, яка детально пояснює це. Він просто підсумовував цю статтю своїм коментарем.
Сервіс

7
Вибачте, але я не той, хто сюди їздить. Відповідь на ваше запитання дуже проста: закріпіть клас, коли ви не хочете підтримувати спадщину. Це воно.
Роберт Харві

Відповіді:


27

Зрозуміти це не так складно. sealedстворено СПЕЦІФІЧНО для Microsoft, щоб полегшити їхнє життя, заощадити тонни грошей та допомогти їхній репутації. Оскільки це мовна функція, всі інші можуть також використовувати її, але ВАМ, ймовірно, ніколи не потребуватиме використання запечатаного.

Більшість людей скаржаться на неможливість розширення класу, і якщо вони це роблять, то вони кажуть, що всі знають, що відповідальність за розробники є змусити його працювати правильно. Це правильно, ОКРЕМИ ці ж люди не мають поняття про історію Windows і одну з проблем sealedнамагаються вирішити.

Припустимо, розробник розширив основний клас .Net (оскільки герметичний не існував) і змусив його працювати бездоганно. Так, для розробника. Розробник постачає товар замовнику. Додаток розробника працює чудово. Замовник задоволений. Життя чудове.

Тепер Microsoft випускає нову операційну систему, яка включає виправлення помилок саме в цьому .Net core class. Замовник хоче йти в ногу з часом і вирішує встановити нову операційну систему. Раптом додаток, який так сподобається клієнту, вже не працює, оскільки він не враховував помилок, які були виправлені в базовому класі .Net.

Хто приймає провину?

Ті, хто знайомий з історією Microsoft, знають, що винна нова ОС Microsoft, а не прикладне програмне забезпечення, яке неправильно використовує бібліотеки Windows. Тоді Microsoft зобов’язується вирішити проблему замість компанії-додатка, яка створила проблему. Це одна з причин, чому код Windows став роздутим. З того, що я прочитав, код операційної системи Windows засипаний конкретними if-then перевіряє, чи працює певна програма та версія, і якщо так, то виконуйте якусь спеціальну обробку, щоб програма могла функціонувати. Це багато грошей, витрачених Microsoft на виправлення некомпетентності іншої компанії.

Використання sealedне повністю усуває наведений вище сценарій, але це допомагає.


4
@Cawas Це досить важко зловживати цим. Ерік Ліпперт неодноразово заявляв, що всі класи, як і методи, були sealedза замовчуванням, за винятком випадків, коли спеціально не розпечатані, просто тому, що так мало класів насправді призначені для успадкування. Набагато ймовірніше, що ваш клас не був побудований на його підтримку, і ви повинні бути впевнені, що витратили цей чорт часу, якщо ви виходите зі свого шляху, щоб позначити його як незапечатаний.
Сервіс

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

2
@Cawas Переважна більшість класів, написаних більшістю розробників, ніколи не потребуватимуть спадкування, і вони не пишуться для підтримки успадкування. Це можна швидко та ефективно передати читачам / користувачам коду, зробивши тип sealed. Якби це був насправді варіант за замовчуванням, то це означало б, що якщо хтось успадковує від типу, то він би знав, що він створений для його підтримки.
Сервіс

2
Розпакування класу не означає, що клас був створений для його підтримки. Це просто означає, що хтось хотів успадкувати від класу і розпечатав його. У кращому випадку використання запечатаного просто змусить розробників переписати існуючу функціональність (еквівалентну запечатаному класу), але частіше за все, якщо вихідний код доступний, вони просто розблокують його, не враховуючи жодних наслідків. Запечатувати конкретно і рідко встановлювати, краще, тому що тоді розробник може захотіти з'ясувати, чому цей клас запечатаний. Занадто багато запечатаних класів, і їм буде байдуже, чому.
Данк

1
Також безпека - це привід використовувати його! Розглянемо додаток із піском, який намагається отримати доступ до файлу. Пісочниця може перевірити назви файлів-рядків, але що робити, якщо зловмисник може надіслати вам мутант, String а потім вимкнути його після перевірки безпеки, але до вводу-виводу? Я вважаю, що такий тип сценарію є тим, чому Java Stringпозначений final(аналогічно sealed), і я ставлю на те саме, що логіка лежить в основі деяких рішень C #.
Дарієн

23

sealedвикористовується для вказівки, що автор класу не створив його у спадок. Нічого менше, нічого більше.

Правильно спроектувати інтерфейс вже досить складно для багатьох програмістів. Правильне проектування класу, який може бути успадковано, додає труднощів та рядків коду. Більше рядків написаного коду означає більше коду для підтримки. Щоб уникнути цієї зростаючої складності, sealedможна показати, що клас ніколи не був призначений у спадок, і в цьому контексті герметизація класу є цілком коректним рішенням проблеми .

Уявіть випадок, з CustomBoeing787якого походить клас Airliner. Це CustomBoeing787відміняє деякі захищені методи Airliner, але не всі. Якщо у розробника є достатньо часу, і він того вартий, він може перевірити клас, щоб переконатися, що все працює так, як очікувалося, навіть у контексті, коли викликаються неперевірені методи (наприклад, захищені сеттери, які змінюють стан об'єкта). Якщо той же розробник (1) не має часу, (2) не хоче витрачати додаткові сотні чи тисячі доларів свого боса / замовника, або (3) не хоче писати додатковий код, якого він не робить потрібні зараз (YAGNI), тоді він може:

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

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

Це гарна ідея запечатати якомога більше занять чи якомога менше? З мого досвіду, остаточної відповіді немає. Деякі розробники схильні використовувати sealedзанадто багато; інших не хвилює питання про те, як клас буде успадкований та яку проблему він може викликати. Враховуючи таке використання, проблема подібна до тієї, яка полягає у визначенні, чи повинні програмісти використовувати два чи чотири пробіли для відступу: правильної відповіді немає.


Гаразд ... Вибачте, якщо я знову звучу агресивно, але я просто хочу тут бути чітким і напористим ... Я можу зрозуміти лише те, що ви щойно написали будь-яким із двох способів, якби ви писали tl;drтут. Це або "Ні, немає жодної вагомої причини" , або "Я думаю, що немає вагомих причин, але я також не знаю". . Для мене "жодна остаточна відповідь" не є жодною з таких.
Крегокс

6
sealedвикористовується для вказівки, що автор класу не створив його у спадок. Це ваша єдина вагома причина.
Роберт Харві

Це настільки вагома причина, як дати вам велосипед без вогнів і примусового виконання, так чи інакше, ви не можете додати світло.
Крегокс

2
@Cawas Як так? У цьому контексті це не важливо для велосипеда будівельника , щоб гарантувати , що велосипед не має світла, але часто є важливим для користувача такого типу , щоб гарантувати , що реалізація є особливо Конкретної реалізацією. Ви виконуєте необхідні обмеження. У деяких випадках люди можуть додати обмеження, яке насправді не потрібно; ви навели приклад цього. Тільки тому, що обмеження неправильно використовується в одному місці, не означає, що ви ніколи ні в чому не повинні обмежувати.
Сервіс

1
Також безпека - це привід використовувати його! Розглянемо додаток із піском, який намагається отримати доступ до файлу. Пісочниця може перевірити назви файлів-рядків, але що робити, якщо зловмисник може надіслати вам мутант, String а потім вимкнути його після перевірки безпеки, але до вводу-виводу? Я вважаю, що такий тип сценарію є тим, чому Java Stringпозначений final(аналогічно sealed), і я ставлю на те саме, що логіка лежить в основі деяких рішень C #.
Дарієн

4

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

Тепер у C # stringє sealed, ви не можете успадкувати його, але припустимо на секунду, що це було не так. Якщо ви це зробили, то хтось може написати такий клас:

public class EvilString// : String
{
    public override string ToString()
    {
        throw new Exception("I'm mean");
    }
    public override bool Equals(object obj)
    {
        return false;
    }
    public override int GetHashCode()
    {
        return 0;
    }
}

Це був би клас струн, який порушує всілякі властивості, які дизайнери stringзнали, що це правда. Вони знали, що Equalsметод буде транзитивним, це не так. Чорт, цей метод рівних навіть не симетричний, оскільки рядок може бути рівним йому, але він не буде рівний цій рядку. Я впевнений, що існують всілякі програмісти, які написали код під припущенням, що ToStringметод stringне кине виключення для ненульових значень. Тепер ви зможете порушити це припущення.

Існує будь-яка кількість інших класів, для яких ми могли б це зробити, і всілякі інші припущення, які ми могли б порушити. Якщо ви видалите мовну функцію дляsealedто мовні дизайнери тепер повинні почати облік таких речей у всьому коді своєї бібліотеки. Їм потрібно проводити всілякі перевірки, щоб переконатися, що розширені типи типів, які вони бажають використовувати, будуть написані «належним чином», що може бути дуже дорогою справою (як у розроблений час, так і під час виконання). Будучи в змозі запечатати клас, вони можуть переконатися, що це неможливо, і будь-які твердження, які вони роблять щодо відомостей про реалізацію власних типів, не можуть бути порушені, за винятком тих типів, які навмисно призначені для розширення. Для тих типів, які розроблені для розширення, ви знайдете, що мовний код повинен бути набагато захиснішим щодо того, як він працює з ними.


Але ви можете порушити це припущення у своєму коді . Це не так, як ви захоплюєте джерело String і редагуєте його. Дизайнерам не потрібно було б це пояснювати, оскільки це 1 листок, 1 відділення, 1 клієнт, який використовує його на власний ризик та розсуд. Він не поширюватиметься звідти, якщо інші клієнти не захочуть цього робити. І так далі.
Крегокс

3
@Cawas І якщо виняток викидається в несподіваний час і ресурс просочується в результаті, або клас залишається у невизначеному стані та функціонує неналежно? Цей випадок трохи нерозумний, але це може бути легко, коли хтось пише реалізацію, яку, на їхню думку, є розумною, але періодично кидає, коли вона не повинна або не працює з певними значеннями. Потім вони скаржиться, коли код мови не працює. Бажано просто не дозволяти людям робити те, що мова не зможе підтримати.
Сервіс

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

2
@Cawas stringТип не є кодом компілятора. Це частина мовного коду. Зовсім інше. У будь-якому випадку я лише вибрав один приклад. Ви можете підібрати більшість будь-якого запечатаного класу у всьому BCL і використовувати його як приклад.
Сервіс

4
@Cawas: Я думаю, що вам може не вистачити тут аспект підтримки клієнтів. Якщо ви дозволяєте класу бути спадковим, клієнти збираються успадковувати його, а потім вони передзвонять вам, коли він перерветься. Ви можете цілий день говорити їм, що вони успадковують цей клас на свій страх і ризик, але ви все одно збираєтесь отримати дзвінок, тому що ви дозволили їм успадкувати його, тому вони вважають, що це безпечно зробити.
Роберт Харві

3

Чи є якісь вагомі причини використовувати герметичну?

Ен? Не часто. Я використовував тільки запечатаний , коли у мене є незмінний тип (або яке - небудь інше обмеження) , що на насправді дійсно потрібно залишатися непорушними і я не можу довіряти Спадкоємці до furfill цієї вимоги , без введення тонку, catastropic помилки в систему.

Припустимо, є вагома причина використовувати герметичну, і ми повинні використовувати її як за замовчуванням для всього, що ми робимо із спадщиною?

Ми використовуємо спадщину для тих речей, які не є типовими. Навіть якщо композиція надає перевагу над спадщиною (і вона є), це не означає, що спадщину слід відкидати. Це означає, що у наслідування є деякі сутнісні проблеми, які він вводить у дизайн та код ремонту коду, а композиція робить майже те саме, що з (загалом) меншими проблемами. І це означає, що навіть якщо прихильний склад, спадкування корисне для певних наборів проблем.

Я не маю на увазі бути занадто злим, але якщо ви щойно чули про тест SOLID та блок, можливо, вам слід вийти з-під вашої рок і насправді написати код. Речі не чіткі, і рідко "завжди робимо X" або "ніколи не використовуй Y" або "Z найкраще" буде правильним способом (як здається, ти тяжієш до того, базуючись на поглядах свого питання). Коли ви пишете код, ви можете бачити випадки, коли це sealedможе бути добре, і випадки, коли це викликає у вас горе - як і будь-який інший компроміс.


На мій погляд, це та "уникнути необхідності підтримувати спадщину для клієнтів", які Роберт не хоче докладати, є найбільш перспективними відповідями ... Можливо, ви могли б детальніше зупинитися на тих випадках, коли ви користуєтесь sealed, будь ласка?
Крегокс

@Cawas - я не впевнений, що зможу добре. Я дуже рідко це роблю, і це часто є компромісом, коли гарантія того, що щось залишається незмінним (для оптимізації продуктивності, спрощення дизайну), коштує нездатність успадкувати об'єкт.
Теластин

Круто. Данк уже його занурив! : P Дякую за відповідь. І ти був єдиним, хто підбирав мої «найтонші підказки» щодо моєї експертизи. Схоже, люди припускали, що я знаю більше, я не знаю ... Але я б хотів, щоб "просто кодування" вивело мене з цієї скелі. Можливо, я застосовую ці поняття якимось чином, не так процедурно, як, напевно, слід.
cregox

3

Перш за все, слід прочитати публікацію Еріка Ліпперта про те, чому Microsoft запечатує свої класи.

http://blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx

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

По-третє, використання опломбованого стимулює склад над спадщиною, що є доброю звичкою потрапляти. Використання композиції над успадкуванням означає, що ви не можете порушити принцип заміни Ліскова, і ви слідуєте принципу "Відкрити / закрити". sealedОтже, це ключове слово, яке допомагає вам виконувати два з п’яти найважливіших принципів програмування oo. Я б сказав, що це робить його дуже цінною особливістю.


Перша частина вже вказана в коментарях до питання. Друга частина - просто більше міркувань без реальних причин. Третя частина, хоч і вже наближалася в іншому місці, може щось до цього зробити. Я б зосередився на цьому.
Крегокс

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

Це залежить від того, контролюєте ви базу коду чи ні. Якщо ви запечатуєте класи, ви завжди можете їх розгортати пізніше, якщо потрібно.
Стівен

2

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

З одного боку, деякі люди хочуть, щоб все було "відкрито", а тягар, щоб усе працювало правильно, лежить на людині, яка розширює клас. Ось чому класи за замовчуванням відкриті для успадкування. І чому методи Java за замовчуванням всі віртуальні.

З іншого боку, деякі хочуть, щоб усе було закрито за замовчуванням і надали варіанти для його відкриття. У цьому випадку автор базового класу повинен забезпечити все, що він робить "відкритим", безпечним для використання будь-яким уявним чином. Ось чому в C # всі методи за замовчуванням є невіртуальними і їх потрібно оголосити віртуальними, щоб їх перекрити. Також для тих людей, які повинні бути способом обійти "відкриті" параметри за замовчуванням. Як і зробити клас запечатаним / заключним, тому що вони бачать, що хтось походить із класу, велика проблема дизайну їхнього власного класу.


Це більше подобається! Це може бути вагомою причиною ... "Тому що люди хочуть її закрити". І це також те, що я намагаюся сказати у запитанні: схоже, що невіртуальні класи в C ++ можуть бути замінені sealedне може. Як ми можемо успадкувати їх? Все, що я читав - ми не можемо. Колись. Не знаю. Я вже назад і назад з цього приводу вже 4 місяці, відколи вперше почув про запечатане. І я досі не знаю, як це зробити правильно, коли мені потрібно щось модифікувати на закритому класі. Отже, я не бачу "варіанту його відкрити"!
Крегокс

4
З цієї причини методи класу C ++ за замовчуванням не є віртуальними. Зробити метод віртуальним означає, що в таблиці пошуку методу повинні бути додаткові накладні витрати, а у C ++ є філософія, що ви платите за накладні витрати лише тоді, коли вам потрібна функція.
Майкл Шоу

@Ptolemy Добре, я її видалив. Я ніколи не повинен був це писати, бо знав, що люди починають скаржитися на це.
Ейфорія

ей, я цілком вдячний, що якщо ви хочете стверджувати, що люди хочуть писати закриті класи за замовчуванням, і доведеться активно вибирати їх, тоді вам доведеться чіплятися за соломинку
Майкл Шоу

IMO надзвичайно схожий на приватні / захищені / публічні дебати, коли мова йде про API-інтерфейси: Це сильно залежить від того, хто керує класом, хто хоче успадкувати клас, спілкування між ними та того, як часто виходять нові версії.
Дарієн

-2

Проблема із запечатаною в C # полягає в тому, що вона досить остаточна. За 7 років комерційної розробки C # єдине місце, де я бачив це, - це класи Microsoft .NET, де я вважаю, що я мав законну причину розширити рамковий клас, щоб реалізувати скориговану поведінку, і тому що клас був запечатаний, я не міг .

Неможливо написати клас, думаючи про всі можливі способи його використання, і вирішивши, що жоден з них не є законним. Так само якщо безпека фреймворку залежить від того, що клас не успадковується, то у вас є вада дизайну безпеки.

Отже, на закінчення, я твердо переконаний, що герметизація не виконує корисних цілей, і ніщо, що я читав тут, поки що не змінило цю думку.

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

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

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

  3. Аргумент 3 полягає в тому, що як розробник класу, це мій вибір, чи дозволяти вам розширити його, як частину мого дизайну класу.

Аргумент 1, здається, є аргументом того, що ви кінцевий програміст не знаєте, як використовувати мій код. Це може бути так, але якщо ви все-таки дозволите мені отримати доступ до інтерфейсу об'єктів, це все-таки вірно, що я використовую ваш об’єкт і здійснюю дзвінки до нього, не розуміючи, як ним користуватися, і тому я можу зробити такий же шкоду таким чином . Це слабке обґрунтування потреби в печатці.

Я розумію, звідки береться фактична база для аргументу 2. Зокрема, коли microsoft поставив додаткові перевірки ОС на виклики win32 api для виявлення неправильних викликів, які покращили загальну стабільність Windows XP порівняно з Windows NT, але за короткий термін багато програм були вирвані під час виходу Windows XP. Microsoft вирішила це, поставивши "правила" для цих перевірок, щоб ігнорувати, коли додаток X порушує це правило, його відомий помилку

Аргумент 2 - поганий аргумент, тому що герметизація в кращому випадку не має жодного значення для цього, тому що якщо в бібліотеці .NET є помилка, у вас немає іншого вибору, як знайти роботу, і коли вийде виправлення мікрософт, цілком ймовірно означає, що ваша робота, навколо якої залежить від порушеної поведінки, зараз порушена. Незалежно від того, чи працювали ви над цим, використовуючи спадщину або інший додатковий код обгортки, коли код буде виправлено, ваша робота навколо буде порушена.

Аргумент 3 - єдиний аргумент, який має будь-яку субстанцію для виправдання свого самоврядування. Але вона все ще слабка. Це просто суперечить зерну коду повторного використання.


2
/ мені надсилає електронний лист до Microsoft, будь ласка, ви можете розкрити для мене клас X та відправити нову версію .NET. з повагою, .... Як я вже говорив, єдиний раз у комерційній розробці я побачив герметичний клас, розімкнути його не вдалося.
Майкл Шоу

6
It is impossible to write a class thinking about every possible way it could be used- Саме це є причиною того, що багато класів Framework запечатано ... Це виключає необхідність думати про кожен можливий спосіб, як хтось може розширити клас.
Роберт Харві

5
Якби ви змогли її розпечатати, не було б великого сенсу в її запечатуванні, чи не так?
Роберт Харві

2
@Ptolemy Дозволити людям розширювати ваш клас - це особливість . Той, який вимагає значної кількості зусиль на розробку. Це особливість варто лише обґрунтувати, якщо автор класу може побачити достатню користь у потенційних розширеннях, щоб виправдати зусилля. Якщо вони не можуть виправдати зусилля, і тому тип і його користувачі не побудовані для підтримки розширення, то важливо запобігти цьому, інакше ви технічно не зможете розширити тип, але навряд чи це буде належним чином працювати, коли ти так робиш.
Сервіс

2
@Cawas: Вам просто важко.
Роберт Харві


-8

Як видно з мого питання, я тут не експерт. Але я не бачу причин sealedнавіть існувати.

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

Ну, це виглядає як "прикрити місце і розкрити інше". І це навіть не вирішення проблеми - це просто усунення інструменту : успадкування. Як і будь-який інструмент, він має багато звичок і успадкування від нестабільного класу є ризиком, який ви берете на себе. Хто ризикував, той повинен краще знати.

Можливо, може бути ключове слово stable, тому люди знають, що це безпечніше успадкувати від нього.


2
"Проблема вирішена" - Саме так.
Роберт Харві

@RobertHarvey Це не вирішено, як пояснено прямо в наступному параграфі.
Крегокс

8
Ти просто злий, бо не можеш продовжити клас. Це не означає, що sealedце не корисний інструмент для дизайнерів рамок. Заняття в рамках повинні бути чорними скриньками; вам не слід знати про внутрішні класи класу, щоб мати можливість ним правильно користуватися. Але саме цього вимагає спадщина.
Роберт Харві

Я ніколи не казав, що це не корисно. Я кажу, що не бачу його використання, і вказую, чому. Будь ласка, прошу вас, дайте мені вагомий привід використати це! Навіть якщо це просто "тому, що я хочу слідувати закритому дизайну", це добре. Я не бачу, щоб хтось це чітко пояснював.
Крегокс

7
Доброю причиною є те, що вам не доведеться підтримувати спадщину на закритому класі.
Роберт Харві
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.