Мне просто было интересно, поскольку существование ключевого слова запечатанный указывает на то, что это решение автора класса относительно того, разрешено ли другим классам наследовать от него, почему классы не запечатаны по умолчанию с помощью некоторого ключевого слова, чтобы явно пометить их как расширяемые?
Я знаю, что это несколько иначе, но модификаторы доступа работают именно так. По умолчанию ограничительный и более полный доступ предоставляется только при вставке ключевого слова.
Однако есть большая вероятность, что я не обдумал это как следует, поэтому, пожалуйста, будьте гуманны!
Слишком много раз я встречал запечатанные классы в .NET Framework, в которых я хотел наследовать и переопределять функциональность. То же самое и с внутренними.
язык с объектами и сообщениями, но не с наследованием, не является объектно-ориентированным, а просто объектно-ориентированным
@Chris: Если вы все еще недовольны запечатанными классами .NET Framework, вам может показаться интересным чтение blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx.
Из MSDN: Чтобы определить, следует ли запечатать класс, метод или свойство, вы должны обычно учитывать следующие два момента: 1) Потенциальные преимущества, которые производные классы могут получить за счет возможности настройки вашего класса. 2) Возможность того, что производные классы могут изменить ваши классы таким образом, что они больше не будут работать правильно или так, как ожидалось. . . Я предпочитаю, чтобы, если для меня как автора класса не требуется дополнительной работы, позволяющей другим извлекать из него возможность, я не помечаю его как запечатанный. Но если мой класс не предназначен для вывода каким-либо тонким способом, запечатайте его.
Интересное мнение по этому поводу от бывшего члена команды C# - он хочет, чтобы они сделали запечатанным значение по умолчанию: stackoverflow.com/questions/2164170/…





Я вижу две простые причины:
Я думаю, многие будут утверждать, что большинство классов нет предназначены для наследования от.
Я также утверждаю, что большинство разработчиков не создают свои классы с учетом наследования.
Майк и Стив, если вы будете следовать хорошей практике объектно-ориентированного проектирования, вы будете разрабатывать классы для наследования и повторного использования.
@ Крис: Ни за что. Большинство классов никогда не будут производными, и угадывание того, какие элементы требуют специализации, не только тратит время, но и накладывает ограничения на ход будущих решений по реализации. См. «Эффективная Java» для подробного обсуждения этого.
Если бы я мог проголосовать за комментарий, я бы сделал это за комментарий Джона здесь - это фундаментальный момент - проектирование с учетом наследования действительно требует большой предусмотрительности, и в подавляющем большинстве случаев в этом нет необходимости - так почему по умолчанию то, что потребует разработчиков тратить мозговые циклы ??
Я не припомню, чтобы я слышал обоснование решения о том, что классы не запечатаны по умолчанию. Тем не менее, определенно есть немало людей, которые считают, что C# должен был быть запечатан по умолчанию:
http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/randing-on-the-sealed-keyword.aspx
запечатанные классы предотвратить наследование и поэтому являются мерзостью OO. подробности см. в эта напыщенная речь ;-)
спасибо за проездные голоса против без комментариев - трусы! :-П
Лично я считаю, что наследование реализации сильно преувеличено. И я в целом согласен с утверждением, что значение по умолчанию должно быть запечатано - очень легко испортить наследование. Вместо этого, когда это возможно, обычно следует использовать композицию. Так что я категорически не согласен с вами :) Для меня главными преимуществами объектно-ориентированной разработки являются интерфейсы и полиморфизм.
@ [Phil]: итак, каждый раз, когда вы создаете форму окна, вы инкапсулируете объект Form вместо наследования от System.Windows.Form? Похоже, это требует много дополнительной работы ... Наследование имеет фундаментальное значение; учись, живи, люби ;-)
@ StevenA.Lowe Для процветания я должен указать, что Form был разработан с возможностью расширения, и в этом весь смысл этих дебатов. Нам с вами кажется очевидным, что нужно стремиться к созданию расширяемого кода, однако эмпирические данные показывают, что, к сожалению, слишком многие люди этого не делают. Следовательно, наличие или отсутствие класса не имеет теоретической разницы; эти классы не могут быть расширены, поскольку они не были предназначены для этого, точка. Единственное практическое отличие состоит в том, что в одном случае это очевидно и явно (запечатано), а в другом вы можете обнаружить это, когда он дает сбой во время выполнения.
Вероятно, вы могли бы привести столько же аргументов в пользу запечатанного по умолчанию, сколько и против него. Если бы было наоборот, кто-то разместил бы противоположный вопрос.
Простое получение от незапечатанного класса не меняет поведения класса. Худшее, что может случиться, это то, что новая версия базового класса добавит член с тем же именем, что и производный класс (в этом случае будет просто предупреждение компилятора о том, что вы должны использовать модификатор новый или отвергать) или базовый класс запечатан (что является конструктивным запретом, если класс уже выпущен в открытый доступ). Произвольное разделение на подклассы по-прежнему соответствует Принцип замены Лискова.
Причина, по которой члены не могут быть переопределены по умолчанию в C#, заключается в том, что переопределение метода может изменить поведение базового класса так, как не ожидал автор базового класса. Делая его явно абстрактным или виртуальным, он говорит о том, что автор осознает, что он может измениться или иным образом находится вне его контроля, и автор должен был это принять во внимание.
Я бы сказал, что это просто ошибка. Я знаю многих людей (включая меня), которые считают, что классы действительно должны быть запечатаны по умолчанию. В этом лагере есть как минимум пара человек в команде разработчиков C#. Маятник несколько отклонился от наследования с момента создания C#. (Конечно, у него есть свое место, но я использую его относительно редко.)
Как бы то ни было, это не единственная ошибка в том, что вы слишком близки к Java: лично я бы предпочел, чтобы Equals и GetHashCode не были в объекте, и что вам также нужны определенные экземпляры Monitor для блокировки ...
кто в команде C# был профессионалом?
Я считаю, что Эрик Липперт и Сайрус тоже. (Хотя я не думаю, что кто-то из них был в команде над v1.)
Если бы GetHashCode не был в объекте, то каждому агрегатору (даже не наследнику) нужно было бы предоставить доступ к частным объектам каждого типа, и агрегаторам пришлось бы накатывать свой собственный хешер для каждого типа. Вы действительно думаете, что это уменьшит боль при программировании?
@Windows: Ничего из этого не будет. Вы могли бы необязательно реализовать равенство и GetHashCode там, где это имеет смысл, реализуя интерфейс. Может быть включен системный компаратор IEqualityComparer, который выполняет сравнение идентичности. Другие сравнения могут быть основаны на общедоступных свойствах. Было бы хорошо.
Три основные ошибки C#: изменяемый по умолчанию, незапечатанный по умолчанию, допускающий значение NULL по умолчанию.
Я читал эту статью (blog.stephencleary.com/2010/03/…), где она перенаправлялась на ваш ответ, и в блоге также говорится, что если класс используется для наследования, тогда он должен быть помечен как запечатанный, но что мы получим, если мы отметим каждый класс как запечатанный, если он не будет принять участие в наследстве?
@ Learning-Overthinker-Confused: Какую строку точный сообщения в блоге вы имеете в виду? Что вы имеете в виду под «используется для наследования» и «участвует в наследовании»? (Класс Каждый принимает участие в наследовании, поскольку он наследуется, по крайней мере, от System.Object.) Я думаю, вы могли неправильно понять сообщение. В конце Стивен пишет, что он запечатывает каждый класс пока не: «он действительно должен быть базовым классом».
Хорошо. Допустим, у меня есть класс под названием Product (Автономный класс), и нет класса, который наследуется от этого класса Product, поэтому достаточной причины для того, чтобы пометить класс продукта как запечатанный?
@ Learning-Overthinker-Confused: я бы остановился и спросил себя, можете ли вы придумать причину, по которой к подклассифицирует его. Если есть, вероятно, это заслуживает дополнительных дизайнерских работ. Если нет, запечатайте его.
В сообщении в блоге, написанном Стивеном Клири, говорится, что он запечатывает каждый класс, если «он действительно не должен быть базовым классом», поэтому есть ли какое-либо преимущество в производительности от запечатывания каждого класса? Я просто пытаюсь понять причину, по которой он говорит это
@ Learning-Overthinker-Confused: потому что это делает намерение явным. Другими словами, это «спроектировать для наследования или запретить». Это не имеет ничего общего с производительностью - если есть улучшение производительности, это просто бонус.
По моему мнению не должно быть синтаксиса по умолчанию, таким образом вы всегда явно пишете то, что хотите. Это заставляет кодировщика больше понимать / думать.
Если вы хотите, чтобы класс был наследуемым, вы пишете
public extensible class MyClass
иначе
public sealed class MyClass
Кстати, я думаю, что то же самое должно быть с модификаторами доступа, запретить модификаторы доступа по умолчанию.
Хороший момент: вам всегда нужно четко понимать, что вы делаете, вместо того, чтобы сознательно или неосознанно возвращаться к невидимым настройкам по умолчанию.
вы можете рассмотреть возможность использования абстрактного модификатора для целей наследования
Я бы повторно использовал существующее ключевое слово base "общедоступный базовый класс ..."
А что было бы, если бы не было указано ключевое слово? Просто public class MyClass
Я понимаю вашу точку зрения - хотя в этом случае все может быть очень многословным. Принятие разумных решений по умолчанию, обычных решений для разработчика кажется разумным, как положено ...
80% функций Word не используются. 80% классов не наследуются от. В обоих случаях время от времени кто-то приходит и хочет использовать или повторно использовать функцию. Почему исходный конструктор должен запрещать повторное использование? Пусть повторный пользователь решит, что они хотят использовать повторно.
Это аргумент против существования ключевого слова sealed, а не значения по умолчанию :)
По той же причине, почему объекты по умолчанию не являются частными
или же
чтобы соответствовать аналогу объекта, то есть объекты не являются частными по умолчанию
Просто догадываюсь, потому что, в конце концов, это дизайнерское решение языка, а то, что создатели говорят, является каноническим материалом.
Я бы сказал, что если вы сделали классы запечатанными по умолчанию, это означает, что вы НЕ должны использовать объектно-ориентированный язык.