В С# и С++/CLI ключевое слово sealed
(или NotInheritable
в VB) используется для защиты класса от любой вероятности наследования (класс будет не наследуемым). Я знаю, что одной из особенностей объектно-ориентированного программирования является наследование, и я чувствую, что использование sealed
идет вразрез с этой функцией, оно прекращает наследование.
Есть ли пример, который показывает преимущество sealed
и когда важно его использовать?
Когда и почему вы запечатываете класс?
Ответ 1
1) В классе, который реализует функции безопасности, так что исходный объект не может быть "олицетворен".
2) В более общем плане, я недавно обменялся с человеком в Microsoft, который сказал мне, что они пытались ограничить наследование теми местами, где это действительно было в полной мере, потому что оно становится дорогостоящим, если его не лечить.
Запечатанное ключевое слово сообщает CLR, что еще нет класса для поиска методов, и это ускоряет работу.
В большинстве инструментов повышения производительности на рынке в настоящее время вы найдете флажок, который запечатает все ваши классы, которые не унаследованы.
Будьте осторожны, потому что, если вы хотите разрешить плагины или обнаружение сборки через MEF, у вас возникнут проблемы.
Ответ 2
В дополнении к Бабуину отличный ответ:
3) Если класс не предназначен для наследования, подклассы могут нарушать инварианты класса. Это действительно применимо только в том случае, если вы создаете публичный API, но, как правило, я запечатываю любой класс, явно не предназначенный для подкласса.
В соответствующей заметке, применимой только к незапечатанным классам: любой созданный метод virtual
является точкой расширения или, по крайней мере, выглядит как точка расширения. Объявление методов virtual
должно быть сознательным решением. (В С# это сознательное решение, в Java это не так.)
EDIT: некоторые релевантные ссылки:
- Эффективная Java, 2nd Edition от Джошуа Блоха. См. Пункт 17 (требуется подписка на Safari).
- Эффективный Java-элемент 17: Дизайн и документ для наследования или запрет на него (обсуждение одного и того же элемента)
Также обратите внимание, что Kotlin по умолчанию закрывает классы; его ключевое слово open
противоположно Java final
или sealed
для С#. (Конечно, нет универсального соглашения о том, что это хорошая вещь.)
Ответ 3
Я думаю, что у этого сообщения есть хорошая точка зрения, конкретный случай заключался в том, чтобы пытаться применить незапечатанный класс к любому случайному интерфейсу, компилятор не бросает ошибку; но когда используется печать, компилятор выдает ошибку, которую он не может преобразовать. Запечатанный класс обеспечивает дополнительную защиту доступа к коду.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla