Почему классы не запечатаны по умолчанию?

Мне просто было интересно, поскольку существование ключевого слова запечатанный указывает на то, что это решение автора класса относительно того, разрешено ли другим классам наследовать от него, почему классы не запечатаны по умолчанию с помощью некоторого ключевого слова, чтобы явно пометить их как расширяемые?

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

Однако есть большая вероятность, что я не обдумал это как следует, поэтому, пожалуйста, будьте гуманны!

Я бы сказал, что если вы сделали классы запечатанными по умолчанию, это означает, что вы НЕ должны использовать объектно-ориентированный язык.

Jon Limjap 31.10.2008 05:44

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

Chris Pietschmann 31.10.2008 09:33

язык с объектами и сообщениями, но не с наследованием, не является объектно-ориентированным, а просто объектно-ориентированным

Steven A. Lowe 25.03.2009 06:05

@Chris: Если вы все еще недовольны запечатанными классами .NET Framework, вам может показаться интересным чтение blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx.

Brian 12.05.2011 01:17

Из MSDN: Чтобы определить, следует ли запечатать класс, метод или свойство, вы должны обычно учитывать следующие два момента: 1) Потенциальные преимущества, которые производные классы могут получить за счет возможности настройки вашего класса. 2) Возможность того, что производные классы могут изменить ваши классы таким образом, что они больше не будут работать правильно или так, как ожидалось. . . Я предпочитаю, чтобы, если для меня как автора класса не требуется дополнительной работы, позволяющей другим извлекать из него возможность, я не помечаю его как запечатанный. Но если мой класс не предназначен для вывода каким-либо тонким способом, запечатайте его.

zumalifeguard 18.09.2014 23:52

Интересное мнение по этому поводу от бывшего члена команды C# - он хочет, чтобы они сделали запечатанным значение по умолчанию: stackoverflow.com/questions/2164170/…

niico 12.12.2016 16:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
31
6
3 542
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Я вижу две простые причины:

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

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

Michael Burr 31.10.2008 04:37

Я также утверждаю, что большинство разработчиков не создают свои классы с учетом наследования.

Steve Horn 31.10.2008 05:45

Майк и Стив, если вы будете следовать хорошей практике объектно-ориентированного проектирования, вы будете разрабатывать классы для наследования и повторного использования.

Chris Pietschmann 31.10.2008 09:29

@ Крис: Ни за что. Большинство классов никогда не будут производными, и угадывание того, какие элементы требуют специализации, не только тратит время, но и накладывает ограничения на ход будущих решений по реализации. См. «Эффективная Java» для подробного обсуждения этого.

Jon Skeet 31.10.2008 10:07

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

Phil 08.12.2009 19:25

Я не припомню, чтобы я слышал обоснование решения о том, что классы не запечатаны по умолчанию. Тем не менее, определенно есть немало людей, которые считают, что C# должен был быть запечатан по умолчанию:

http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/randing-on-the-sealed-keyword.aspx

запечатанные классы предотвратить наследование и поэтому являются мерзостью OO. подробности см. в эта напыщенная речь ;-)

спасибо за проездные голоса против без комментариев - трусы! :-П

Steven A. Lowe 24.03.2009 18:13

Лично я считаю, что наследование реализации сильно преувеличено. И я в целом согласен с утверждением, что значение по умолчанию должно быть запечатано - очень легко испортить наследование. Вместо этого, когда это возможно, обычно следует использовать композицию. Так что я категорически не согласен с вами :) Для меня главными преимуществами объектно-ориентированной разработки являются интерфейсы и полиморфизм.

Phil 08.12.2009 19:21

@ [Phil]: итак, каждый раз, когда вы создаете форму окна, вы инкапсулируете объект Form вместо наследования от System.Windows.Form? Похоже, это требует много дополнительной работы ... Наследование имеет фундаментальное значение; учись, живи, люби ;-)

Steven A. Lowe 08.12.2009 22:47

@ StevenA.Lowe Для процветания я должен указать, что Form был разработан с возможностью расширения, и в этом весь смысл этих дебатов. Нам с вами кажется очевидным, что нужно стремиться к созданию расширяемого кода, однако эмпирические данные показывают, что, к сожалению, слишком многие люди этого не делают. Следовательно, наличие или отсутствие класса не имеет теоретической разницы; эти классы не могут быть расширены, поскольку они не были предназначены для этого, точка. Единственное практическое отличие состоит в том, что в одном случае это очевидно и явно (запечатано), а в другом вы можете обнаружить это, когда он дает сбой во время выполнения.

tne 24.05.2015 06:10

Вероятно, вы могли бы привести столько же аргументов в пользу запечатанного по умолчанию, сколько и против него. Если бы было наоборот, кто-то разместил бы противоположный вопрос.

Простое получение от незапечатанного класса не меняет поведения класса. Худшее, что может случиться, это то, что новая версия базового класса добавит член с тем же именем, что и производный класс (в этом случае будет просто предупреждение компилятора о том, что вы должны использовать модификатор новый или отвергать) или базовый класс запечатан (что является конструктивным запретом, если класс уже выпущен в открытый доступ). Произвольное разделение на подклассы по-прежнему соответствует Принцип замены Лискова.

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

Я бы сказал, что это просто ошибка. Я знаю многих людей (включая меня), которые считают, что классы действительно должны быть запечатаны по умолчанию. В этом лагере есть как минимум пара человек в команде разработчиков C#. Маятник несколько отклонился от наследования с момента создания C#. (Конечно, у него есть свое место, но я использую его относительно редко.)

Как бы то ни было, это не единственная ошибка в том, что вы слишком близки к Java: лично я бы предпочел, чтобы Equals и GetHashCode не были в объекте, и что вам также нужны определенные экземпляры Monitor для блокировки ...

кто в команде C# был профессионалом?

Mark Cidade 31.10.2008 09:29

Я считаю, что Эрик Липперт и Сайрус тоже. (Хотя я не думаю, что кто-то из них был в команде над v1.)

Jon Skeet 31.10.2008 09:59

Если бы GetHashCode не был в объекте, то каждому агрегатору (даже не наследнику) нужно было бы предоставить доступ к частным объектам каждого типа, и агрегаторам пришлось бы накатывать свой собственный хешер для каждого типа. Вы действительно думаете, что это уменьшит боль при программировании?

Windows programmer 31.10.2008 10:15

@Windows: Ничего из этого не будет. Вы могли бы необязательно реализовать равенство и GetHashCode там, где это имеет смысл, реализуя интерфейс. Может быть включен системный компаратор IEqualityComparer, который выполняет сравнение идентичности. Другие сравнения могут быть основаны на общедоступных свойствах. Было бы хорошо.

Jon Skeet 07.11.2008 09:24

Три основные ошибки C#: изменяемый по умолчанию, незапечатанный по умолчанию, допускающий значение NULL по умолчанию.

Den 13.06.2016 18:57

Я читал эту статью (blog.stephencleary.com/2010/03/…), где она перенаправлялась на ваш ответ, и в блоге также говорится, что если класс используется для наследования, тогда он должен быть помечен как запечатанный, но что мы получим, если мы отметим каждый класс как запечатанный, если он не будет принять участие в наследстве?

Learning-Overthinker-Confused 02.03.2019 16:55

@ Learning-Overthinker-Confused: Какую строку точный сообщения в блоге вы имеете в виду? Что вы имеете в виду под «используется для наследования» и «участвует в наследовании»? (Класс Каждый принимает участие в наследовании, поскольку он наследуется, по крайней мере, от System.Object.) Я думаю, вы могли неправильно понять сообщение. В конце Стивен пишет, что он запечатывает каждый класс пока не: «он действительно должен быть базовым классом».

Jon Skeet 02.03.2019 22:14

Хорошо. Допустим, у меня есть класс под названием Product (Автономный класс), и нет класса, который наследуется от этого класса Product, поэтому достаточной причины для того, чтобы пометить класс продукта как запечатанный?

Learning-Overthinker-Confused 04.03.2019 09:32

@ Learning-Overthinker-Confused: я бы остановился и спросил себя, можете ли вы придумать причину, по которой к подклассифицирует его. Если есть, вероятно, это заслуживает дополнительных дизайнерских работ. Если нет, запечатайте его.

Jon Skeet 04.03.2019 10:07

В сообщении в блоге, написанном Стивеном Клири, говорится, что он запечатывает каждый класс, если «он действительно не должен быть базовым классом», поэтому есть ли какое-либо преимущество в производительности от запечатывания каждого класса? Я просто пытаюсь понять причину, по которой он говорит это

Learning-Overthinker-Confused 04.03.2019 10:10

@ Learning-Overthinker-Confused: потому что это делает намерение явным. Другими словами, это «спроектировать для наследования или запретить». Это не имеет ничего общего с производительностью - если есть улучшение производительности, это просто бонус.

Jon Skeet 04.03.2019 10:13
Ответ принят как подходящий

По моему мнению не должно быть синтаксиса по умолчанию, таким образом вы всегда явно пишете то, что хотите. Это заставляет кодировщика больше понимать / думать.

Если вы хотите, чтобы класс был наследуемым, вы пишете

public extensible class MyClass

иначе

public sealed class MyClass

Кстати, я думаю, что то же самое должно быть с модификаторами доступа, запретить модификаторы доступа по умолчанию.

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

xyz 31.10.2008 17:34

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

Spoike 18.03.2009 16:13

Я бы повторно использовал существующее ключевое слово base "общедоступный базовый класс ..."

Ðаn 30.09.2010 06:53

А что было бы, если бы не было указано ключевое слово? Просто public class MyClass

cregox 15.05.2013 02:37

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

niico 12.12.2016 16:54

80% функций Word не используются. 80% классов не наследуются от. В обоих случаях время от времени кто-то приходит и хочет использовать или повторно использовать функцию. Почему исходный конструктор должен запрещать повторное использование? Пусть повторный пользователь решит, что они хотят использовать повторно.

Это аргумент против существования ключевого слова sealed, а не значения по умолчанию :)

xyz 31.10.2008 17:27

По той же причине, почему объекты по умолчанию не являются частными

или же

чтобы соответствовать аналогу объекта, то есть объекты не являются частными по умолчанию

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

Другие вопросы по теме