Как проектирование для наследования может вызвать дополнительные расходы? [закрыто]


12

Так что я хотел унаследовать от sealed classв csharp и сгорел. Нет никакого способа распечатать его, если у вас нет доступа к источнику.

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

Я пытался переварить все это с тех пор, но это слишком много для меня. В конце концов, вчера я попробовал это снова. Я снова просмотрел их все, плюс еще несколько:

Наконец, после долгих размышлений я решил серьезно отредактировать исходный вопрос на основе нового названия.

Старый вопрос был слишком широким и субъективным. В основном спрашивал:

  1. В старом названии: одна веская причина использовать запечатанный
  2. В теле: Как правильно модифицировать запечатанный класс? Забыть о наследовании? Использовать композицию?

Но теперь, понимая (что я не сделал вчера), что все sealedделает, это предотвращает наследование , и мы можем и должны действительно использовать композицию вместо наследования , я понял, что мне нужны были практические примеры.

Я предполагаю, что мой вопрос здесь (и на самом деле всегда был) именно то, что мистер Миндор предложил мне в чате : как разработка наследования может привести к дополнительным затратам?


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

11
См. Почему так много классов каркаса запечатаны? Эрик Липперт. Он приводит несколько веских причин запечатывать занятия.
Роберт Харви

9
Тогда вы не читали статью. Вернитесь и прочитайте это снова. Это сводится к следующему: вы не можете предсказать бесчисленные способы, которыми клиент может сломать ваш класс, расширив его. Вы можете обвинить своих клиентов в этом, но именно вам придется их поддерживать.
Роберт Харви

4
@Cawas Он мог, или вы могли бы прочитать статью, которую он связал, которая объясняет это подробно. Он просто резюмировал эту статью со своим комментарием.
Serv

7
Извините, но я не тот, кто разглагольствует здесь. Ответ на ваш вопрос очень прост: закройте класс, если вы не хотите поддерживать наследование. Вот и все.
Роберт Харви

Ответы:


27

Это не так сложно понять. sealedбыл создан специально для Microsoft, чтобы сделать их жизнь проще, сэкономить кучу денег и помочь их репутации. Поскольку это языковая функция, ее могут использовать все остальные, но ВАМ, вероятно, никогда не придется использовать запечатанную.

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

Давайте предположим, что разработчик расширил базовый класс .Net (потому что запечатанный не существует) и заставил его работать идеально. Yay для разработчика. Разработчик доставляет продукт покупателю. Приложение разработчика отлично работает. Клиент счастлив. Жизнь хороша.

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

Кто обвиняет?

Те, кто знаком с историей Microsoft, знают, что виновата будет новая ОС Microsoft, а не прикладное программное обеспечение, которое неправильно использовало библиотеки Windows. Так что теперь Microsoft должна решить проблему, а не компанию, которая ее создала. Это одна из причин, почему код Windows стал раздутым. Из того, что я прочитал, код операционной системы Windows изобилует конкретными проверками if-then, проверяет, работает ли конкретное приложение и версия, и если да, то выполняет некоторую специальную обработку, чтобы позволить программе функционировать. Это огромные деньги, потраченные Microsoft на исправление некомпетентности другой компании.

Использование sealedне полностью исключает приведенный выше сценарий, но помогает.


4
@Cawas Довольно сложно злоупотреблять этим. Эрик Липперт неоднократно заявлял, что он хотел бы, чтобы все классы, такие как методы, были sealedпо умолчанию всеми , если не были специально распечатаны, просто потому, что на самом деле очень немногие классы предназначены для наследования. Гораздо более вероятно, что ваш класс не был создан для его поддержки, и вы должны убедиться, что вы потратили это время на разработку, если вы делаете все возможное, чтобы пометить его как незапечатанный.
Servy

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

2
@Cawas Подавляющее большинство классов, написанных большинством разработчиков, никогда не нужно будет наследовать, и они не написаны для поддержки наследования. Это может быть быстро и эффективно передано читателям / пользователям кода путем создания типа sealed. Если бы это была фактически опция по умолчанию, то это означало бы, что если бы кто-то наследовал от типа, он бы знал, что он создан для его поддержки.
Serv

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

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

23

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

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

Представьте себе случай, когда класс CustomBoeing787является производным от Airliner. Это CustomBoeing787отменяет некоторые защищенные методы Airliner, но не все из них. Если у разработчика достаточно времени, и оно того стоит, он может провести модульное тестирование класса, чтобы убедиться, что все работает, как ожидается, даже в контексте, когда вызываются неопределяемые методы (например, защищенные установщики, которые изменяют состояние объекта). Если тот же разработчик (1) не имеет времени, (2) не хочет тратить дополнительные сотни или тысячи долларов своего босса / клиента, или (3) не хочет писать дополнительный код, он не нужно прямо сейчас (ЯГНИ), тогда он может:

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

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

Является ли хорошей идеей запечатать как можно больше классов или как можно меньше? Из моего опыта нет однозначного ответа. Некоторые разработчики склонны использовать sealedслишком много; другие не заботятся о том, как класс будет унаследован, и о проблеме, которую он может вызвать. При таком использовании проблема аналогична той, которая заключается в определении, должны ли программисты использовать два или четыре пробела для отступа: правильного ответа нет.


Хорошо ... Извините, если я снова звучу агрессивно, но я просто хочу быть ясным и напористым здесь ... Я могу понять, что вы только что написали любым из двух способов, если бы вы написали tl;drздесь. Это либо «Нет, нет ни одной веской причины» , либо «Я думаю, что нет веской причины, но я тоже не знаю». , Для меня «нет окончательного ответа» является одним из тех.
Cregox

6
sealedиспользуется, чтобы указать, что автор класса не разработал его для наследования. Это твоя единственная веская причина.
Роберт Харви

Это такая же веская причина, как дать вам велосипед без огней и усилить его, так или иначе, вы не можете добавить свет.
Cregox

2
@Cawas Как так? В этом контексте это не важно для велосипеда строителя , чтобы гарантировать , что велосипед не имеет света, но часто является важным для пользователя такого типа , чтобы гарантировать , что реализация является особенно Конкретной реализацией. Вы применяете ограничения, которые вам нужны. В некоторых случаях люди могут добавлять ограничения, которые на самом деле не нужны; Вы предоставили пример этого. Тот факт, что ограничение используется неправильно в одном месте, не означает, что вы никогда не должны ничего ограничивать.
Servy

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метод будет переходным, это не так. Черт, этот метод equals даже не симметричен, так как строка может быть равна ему, но она не будет равна этой строке. Я уверен, что есть все виды программистов, которые написали код, предполагая, что ToStringметод stringне будет генерировать исключение для ненулевых значений. Теперь вы сможете нарушить это предположение.

Есть множество других классов, для которых мы могли бы сделать это, и всевозможные предположения, которые мы могли бы нарушить. Если вы удалите функцию языка дляsealedтогда разработчики языка теперь должны начать учитывать подобные вещи во всем коде своей библиотеки. Они должны выполнять все виды проверок, чтобы гарантировать, что расширенные типы типов, которые они хотят использовать, будут написаны «правильно», что может быть очень дорогостоящим делом (как во время разработки, так и во время выполнения). Имея возможность запечатать класс, они могут гарантировать, что это невозможно, и что любые утверждения, которые они делают о деталях реализации своих собственных типов, не могут быть нарушены, за исключением тех типов, которые специально предназначены для расширения. Для тех типов, которые предназначены для расширения, вы обнаружите, что языковой код должен быть гораздо более осторожным в отношении того, как он работает с ними.


Но вы можете нарушить это предположение в своем коде . Это не значит, что вы берете источник String и редактируете его. Дизайнеры не должны были бы это учитывать, потому что это 1 лист, 1 ветка, 1 клиент, которые используют его на свой страх и риск. Он не будет распространяться оттуда, если другие клиенты не захотят это делать. И так далее.
Cregox

3
@Cawas А если в неожиданное время выбрасывается исключение и в результате происходит утечка ресурса, или класс остается в неопределенном состоянии и функционирует ненадлежащим образом? Этот случай немного глуп, но может легко случиться так, что кто-то напишет реализацию, которая, по его мнению, является разумной, но иногда выдает ее, когда это не следует, или не работает с определенными значениями. Затем они будут жаловаться, когда код языка не работает. Желательно просто не позволять людям делать вещи, которые язык не сможет поддерживать.
Serv

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

2
@Cawas stringТип не является кодом компилятора. Это часть языкового кода. Полностью отличается. В любом случае, я просто выбрал один пример. Вы можете выбрать практически любой запечатанный класс во всей BCL и использовать его в качестве примера.
Servy

4
@Cawas: я думаю, что вам может не хватать здесь, это аспект поддержки клиентов. Если вы позволите классу наследоваться, клиенты будут наследовать его, а затем они будут звонить вам, когда он ломается. Вы можете сказать им весь день, что они наследуют от этого класса на свой страх и риск, но вы все равно получите вызов, потому что вы позволили им наследовать от него, поэтому они предполагают, что это безопасно.
Роберт Харви

3

Есть ли веская причина использовать герметично?

Enh? Не часто. Я использовал только запечатан , когда у меня есть неизменный тип (или какое - либо другое ограничение) , что на самом деле действительно нужно оставаться незыблемыми и я не могу доверять Наследники к furfill этого требования , не вводя тонкую, catastropic ошибки в систему.

Предположим, что есть веская причина для использования sealed, и мы должны использовать его по умолчанию для всего, что мы делаем с наследованием?

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

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


Для меня это и «чтобы избежать необходимости поддерживать наследование клиентов», которые Роберт не хочет разрабатывать, являются наиболее многообещающими ответами ... Может быть, вы могли бы подробнее остановиться на тех случаях, когда вы используете sealed, пожалуйста?
Cregox

@Cawas - я не уверен, что смогу. Я очень редко делаю это, и часто это компромисс, когда гарантия того, что что-то остается неизменным (для оптимизации производительности, упрощения проектирования), стоит неспособности наследовать от объекта.
Теластин

Это классно. Данк уже окунул! : P Большое спасибо за ответ. И ты был единственным, кто подхватил мои «тонкие намеки» о моей компетентности. Похоже, люди предполагали, что я знаю больше, я не знаю ... Но я бы хотел, чтобы "просто кодирование" вывело меня из этого камня. Возможно, я применяю эти концепции каким-то образом, но не настолько процедурно, как следовало бы.
Cregox

3

Прежде всего, вы должны прочитать пост Эрика Липперта о том, почему Microsoft закрывает свои уроки.

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

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

В-третьих, использование запечатанного поощряет композицию к наследованию, что является хорошей привычкой. Использование композиции поверх наследования означает, что вы не можете нарушить принцип подстановки Лискова, и вы следуете принципу Open / Closed. sealedпоэтому это ключевое слово, которое помогает вам следовать двум из пяти самых важных принципов программирования. Я бы сказал, что это делает его очень ценным.


Первая часть уже указана в комментариях к вопросу. Вторая часть просто больше рассуждений без реальных причин. Третья часть, даже если к ней уже обращались, может иметь к этому какое-то отношение. Я бы сосредоточился на этом.
Cregox

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

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

2

Я думаю, что на этот вопрос нет объективного ответа, и что все зависит от вашей точки зрения.

С одной стороны, некоторые люди хотят, чтобы все было «открыто», и бремя обеспечения того, чтобы все работало правильно, ложится на человека, который расширяет класс. Вот почему классы открыты для наследования по умолчанию. И почему все методы Java являются виртуальными по умолчанию.

С другой стороны, некоторые хотят, чтобы все было закрыто по умолчанию, и предоставляют опции для его открытия. В этом случае автор базового класса должен убедиться, что все, что он делает «открытым», безопасно для использования любым возможным способом. Вот почему в C # все методы не являются виртуальными по умолчанию и должны быть объявлены виртуальными для переопределения. Это также для тех людей, которые должны быть способом обойти «открытые» значения по умолчанию. Как сделать класс запечатанным / окончательным, потому что они видят, что кто-то из класса является большой проблемой для дизайна своего класса.


Это больше похоже на него! Это может быть хорошей причиной ... "Потому что люди хотят закрыть его". И это также то, что я пытаюсь сказать в вопросе: похоже, что не виртуальные классы в C ++ могут быть переопределены. sealedне может. Как мы можем наследовать от них? Все, что я читаю, мы не можем. Когда-либо. Я не знаю. Я изучал эту тему четыре месяца назад, так как впервые услышал о запечатанном. И я до сих пор не знаю, как сделать это правильно, когда мне нужно что-то изменить в запечатанном классе. Итак, я не вижу «возможности открыть его»!
Cregox

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

@Ptolemy Хорошо, я удалил это. Я никогда не должен был писать это, потому что я знал, что люди начинают жаловаться на это.
Эйфорическая

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

IMO очень похож на приватные / защищенные / публичные дебаты, когда дело касается API: это сильно зависит от того, кто контролирует класс, кто хочет наследовать класс, связь между ними и как часто выходят новые версии.
Дариен

-2

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

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

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

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

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

  2. Аргумент 2 заключается в том, что если вы расширяете класс Microsoft, а затем Microsoft внедряете исправление ошибки в этом классе, но ваше расширение полагается на эту ошибку, то ваш код теперь сломан, Microsoft получает вину, а запечатывание предотвращает это.

  3. Аргумент 3 заключается в том, что, как разработчик класса, я выбираю, позволять ли вам его расширять, как часть моего дизайна класса.

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

Я понимаю, откуда взялась фактическая база для arg 2. В частности, когда Microsoft установила дополнительные проверки ОС на вызовах Win32 API для выявления искаженных вызовов, что улучшило общую стабильность Windows XP по сравнению с Windows NT, но при краткосрочной стоимости многие приложения были сломаны при выпуске Windows XP. Microsoft решила эту проблему, добавив «правила» для этих проверок: игнорировать, когда приложение X нарушает это правило, это известная ошибка

Аргумент 2 является плохим аргументом, потому что в лучшем случае запечатанный в принципе не имеет никакого значения к этому, потому что, если в библиотеке .NET есть ошибка, у вас нет другого выбора, кроме как найти обходной путь, и когда выйдет исправление для Microsoft, вполне вероятно, что означает, что ваша работа, которая зависит от нарушенного поведения, теперь нарушена. Независимо от того, работали ли вы с этим, используя наследование или какой-либо другой дополнительный код-обертку, когда код исправлен, ваша работа будет нарушена.

Аргумент 3 является единственным аргументом, который имеет какое-либо обоснование, чтобы оправдать себя. Но это все еще слабо. Это просто идет вразрез с повторным использованием кода.


2
/ me отправляет электронное письмо в Майкрософт, пожалуйста, вы можете распечатать класс X для меня и отправить новую версию .NET. С наилучшими пожеланиями, .... Как я уже сказал, единственный раз, когда я занимался коммерческим развитием, я видел закрытый класс, его невозможно было распечатать.
Майкл Шоу

6
It is impossible to write a class thinking about every possible way it could be used- Именно поэтому многие классы Framework запечатаны ... Это устраняет необходимость думать о том, как кто-то может расширить класс.
Роберт Харви

5
Если бы вы могли распечатать это, не было бы большого смысла запечатывать это, не так ли?
Роберт Харви

2
@Ptolemy Позволить людям расширять ваш класс - это особенность . Тот, который потребляет значительное количество усилий по разработке. Эту функцию стоит оправдать только в том случае, если автор класса может увидеть достаточно преимуществ в потенциальных расширениях, чтобы оправдать усилия. Если они не могут оправдать усилия, и, следовательно, тип и его пользователи не созданы для поддержки расширения, важно предотвратить его, иначе вы технически не сможете расширить тип, но вряд ли он будет работать должным образом, когда Вы делаете это.
Serv

2
@Cawas: Тебе просто сложно.
Роберт Харви


-8

Как видно из моего вопроса, я здесь не эксперт. Но я не вижу причин sealedдаже существовать.

Похоже, это сделано для того, чтобы помочь разработчикам кода в разработке интерфейса. Если вы хотите написать класс, который выйдет в дикую природу, и многие люди унаследуют его, изменение чего-либо в этом классе может нарушить его для слишком многих людей. Таким образом, мы можем запечатать это, и никто не может наследовать. "Проблема решена".

Ну, выглядит как «прикрытие пятна и раскрытие другого». И это даже не решение проблемы - это просто устранение инструмента : наследования. Как и любой инструмент, он имеет много применений, и вы рискуете унаследовать от нестабильного класса. Кто бы ни пошел на этот риск, должен знать лучше.

Возможно, здесь может быть ключевое слово stable, чтобы люди знали, что от него наследовать безопаснее.


2
«Проблема решена» - Точно.
Роберт Харви

@RobertHarvey Это не решено, как объяснено прямо в следующем параграфе.
Cregox

8
Ты просто злишься, потому что не можешь продлить класс. Это вовсе не означает , что sealedне является полезным инструментом для каркасных дизайнеров. Классы в рамках должны быть черными ящиками; вам не нужно знать о внутренностях класса, чтобы правильно его использовать. Все же это именно то, что требует наследования.
Роберт Харви

Я никогда не говорил, что это бесполезно. Я говорю, что не вижу его использования, и указываю, почему. Пожалуйста, я вас умоляю, дайте мне вескую причину использовать его! Даже если это просто «потому что я хочу следовать шаблону закрытого дизайна», это нормально. Я не вижу, чтобы кто-то явно указывал эту причину.
Cregox

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