sealed (Справочник по C#)
При применении к классу модификатор sealed запрещает другим классам наследовать от этого класса. В следующем примере класс B наследует от класса A , но никакие классы не могут наследовать от класса B .
class A <> sealed class B : A <>
Модификатор sealed можно использовать для метода или свойства, которое переопределяет виртуальный метод или свойство в базовом классе. Это позволяет классам наследовать от вашего класса, запрещая им при этом переопределять определенные виртуальные методы или свойства.
Пример
В следующем примере класс Z наследует от класса Y , но Z не может переопределить виртуальную функцию F , которая объявлена в классе X и запечатана в классе Y .
class X < protected virtual void F() < Console.WriteLine("X.F"); >protected virtual void F2() < Console.WriteLine("X.F2"); >> class Y : X < sealed protected override void F() < Console.WriteLine("Y.F"); >protected override void F2() < Console.WriteLine("Y.F2"); >> class Z : Y < // Attempting to override F causes compiler error CS0239. // protected override void F() < Console.WriteLine("Z.F"); >// Overriding F2 is allowed. protected override void F2() < Console.WriteLine("Z.F2"); >>
Чтобы предотвратить переопределение производных классов при определении новых методов или свойств, не назначайте их в качестве виртуальных (virtual).
Нельзя использовать модификатор abstract с запечатанным классом, поскольку абстрактный класс должен наследоваться классом, реализующим абстрактные методы или свойства.
При применении к методу или свойству модификатор sealed всегда должен использоваться с переопределением.
Поскольку структуры неявно запечатаны, их нельзя наследовать.
Дополнительные сведения см. в разделе Наследование.
sealed class SealedClass < public int x; public int y; >class SealedTest2 < static void Main() < var sc = new SealedClass(); sc.x = 110; sc.y = 150; Console.WriteLine($"x = , y = "); > > // Output: x = 110, y = 150
Чтобы наследовать от запечатанного класса, можно применить следующую инструкцию в приведенном выше примере:
class MyDerivedC: SealedClass <> // Error
В результате выдается сообщение об ошибке:
‘MyDerivedC’: cannot derive from sealed type ‘SealedClass’
Комментарии
Чтобы определить, нужно ли запечатывать класс, метод или свойство, имейте в виду следующее:
- потенциальные преимущества, которые производные классы могут получить от возможности настраивать ваш класс;
- вероятность того, что производные классы могут корректировать ваши классы, препятствуя их нормальной работе.
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
См. также
- Справочник по C#
- Руководство по программированию на C#
- Ключевые слова в C#
- Статические классы и члены статических классов
- Абстрактные и запечатанные классы и члены классов
- Модификаторы доступа
- Модификаторы
- override
- virtual
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Как использовать (в чем смысл) sealed?
То есть от класса B наследование не возможно. Ясно.
И уже тут возникает вопрос, почему не написать так
sealed class A <> //class B : A <> //Error
То есть в этом примере я конкретно показал, что наследование не возможно.
В первом примере это показано не настолько явно. Там модификатор sealed был применен к наследуемому классу B и говорилось, что уже от класса B наследование не возможно. То есть какой то третий класс не сможет наследоваться.
И далее идет ещё один пример. (Вот он третий класс Z.)
class X < protected virtual void F() < Console.WriteLine("X.F"); >protected virtual void F2() < Console.WriteLine("X.F2"); >> class Y : X < sealed protected override void F() < Console.WriteLine("Y.F"); >protected override void F2() < Console.WriteLine("Y.F2"); >> class Z : Y < // Attempting to override F causes compiler error CS0239. // protected override void F() < Console.WriteLine("Z.F"); >// Overriding F2 is allowed. protected override void F2() < Console.WriteLine("Z.F2"); >>
Обратите внимание, тут sealed идет в связке с override.
Как я понимаю — sealed — это запечатанный. То есть запечатанное не наследуется, не изменяется и т.д.
Поставили sealed — всё «броня». Никто не изменит, унаследует (за некоторыми исключениями и приемами).
Но вот этот код не верен
class classA < protected string field_1 = null; public sealed string Field_1 < get < return field_1; >set > > class classB : classA < public string Field_1 < get < return field_1; >set < if (value != "1") < field_1 = value; >> > >
Свойство Field_1 не может быть запечатанным т.к. не содержит модификатора override.
Почему? Я не хочу чтобы моё свойство было замещено или переопределено.
Вот ещё мой пример
class classA < protected string field_1 = null; public sealed virtual string Field_1 < get < return field_1; >set > //sealed нужно убрать отсюда > class classB : classA < public override string Field_1 < get < return field_1; >set < if (value != "1") < field_1 = value; >> > //sealed должно быть тут >
Аналогично. Говорит — ставь sealed к override. То есть я могу запретить переопределение свойства classB.
А в чем проблема у classA? Я хочу чтобы его свойство никто не переопределил. Ставлю sealed.
И стандартной ошибки — невозможно. т.к. запечатано не вижу.
Почему для запечатывания требуется override? Почему запечатывание свойства я могу применить только ко второму классу?
- Вопрос задан более трёх лет назад
- 6028 просмотров
Комментировать
Решения вопроса 1

Василий Банников @vabka Куратор тега C#
Токсичный шарпист
Почему для запечатывания требуется override?
По тому что если метод не виртуальный (если у него нет модификатора virtual, override или abstract), то его и так нельзя переопределить.
По-умолчанию все методы не виртуальные
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ответы на вопрос 2
Victor Bomberow @majstar_Zubr
C++, C#, gamedev
Sealed переводится как «запечатанный, герметизированный». Запечатывается что именно?
1) Применение к объявлению класса. Первый пример показывает контекст применения ключевого слова. Функционал наследования запечатывается на первом же уровне наследования. В вашем контрпример не предоставляется новой информации для компилятора, поскольку на моменте компиляции компилятор сам может прийти к выводу, нужно ли при хранении объектов класса использовать указатель на таблицу виртуальных функций. Поэтому там слово sealed синтаксически верно, но лексически бесполезно.
2) Применение к объявлению члену класса. Запечатывание подразумевает наличие кое-чего, что можно запечатать. Именно — функционал наследования. Если вам нужно запечатать функционал наследования на каком-то уровне, вы это делаете. Если вы пытаетесь запечатать что-то на
уровне базового класса, то это в терминологии C# это невыражаемая мысль. Вы не должны использовать в таком случае наследование вообще (не объявлять virtual). Такую мысль могло бы выразить ключевое слово final (С++), но в C# его нет, в нём ООП используется немного в другом в контексте (где, грубо говоря, типы могут быть manged и unmanaged, и у программиста нет полного контроля над sizeof объектов типа).
Именно поэтому поведение реализовано как реализовано и
When applied to a method or property, the sealed modifier must always be used with override.
Почему запечатывание свойства я могу применить только ко второму классу?
В общем-то, функционал наследования исчисляется по уровням наследования, и там он как раз первый, а не второй. Второй класс перед глазами это первый уровень наследования и он запечатывается.
Изолированные классы в C#
Изолированные классы используются для ограничения пользователей от наследования класса. Класс можно изолировать с помощью ключевого слова sealed . Ключевое слово сообщает компилятору, что класс изолирован и, следовательно, не может быть расширен. Никакой класс не может быть производным от изолированного класса.
Ниже приводится синтаксис изолированного класса:
sealed class class_name < // data members // methods . . . >
Метод также можно изолировать, и в этом случае метод не может быть переопределен. Однако метод может быть изолирован в классах, в которых он унаследован. Если вы хотите объявить метод как изолированный, он должен быть объявлен как виртуальный в его базовом классе.
Следующий пример класса определяет изолированный класс в C#:
Далее создайте изолированный класс SealedClass и используйте его из `Program`.
// C# code to define // a Sealed Class using System; // Sealed class sealed class SealedClass < // Calling Function public int Add(int a, int b) < return a + b; >> class Program < // Main Method static void Main(string[] args) < // Creating an object of Sealed Class SealedClass slc = new SealedClass(); // Performing Addition operation int total = slc.Add(6, 4); Console.WriteLine("Total = " + total.ToString()); >>
Вывод :
Итого = 10
Теперь, если попытаться унаследовать класс от изолированного класса, будет выдана ошибка, в которой говорится, что «Класс не может быть производным от изолированного класса .
// C# code to show restrictions // of a Sealed Class using System; class Bird < >// Creating a sealed class sealed class Test : Bird < >// Inheriting the Sealed Class class Example : Test < >// Driver Class class Program < // Main Method static void Main() < >>
Ошибка:
Ошибка CS0509 «Пример»: не может быть производным от изолированного типа «Тест»
Рассмотрим следующий пример изолированного метода в производном классе:
// Программа C # для // демонстрации изолированного класса using System; class Printer < // Функция отображения для // вывода размеров public virtual void show() < Console.WriteLine("display dimension : 6*6"); >// Display Function public virtual void print() < Console.WriteLine("printer printing. \n"); >> // класс-наследник class LaserJet : Printer < // Sealed Display Function // for Dimension printing sealed override public void show() < Console.WriteLine("display dimension : 12*12"); >// Function to override // Print() function override public void print() < Console.WriteLine("Laserjet printer printing. \n"); >> // Класс Officejet не может переопределить метод show // метод изолирован классе родителе LaserJet. class Officejet : LaserJet < // can not override show function or else // compiler error : 'Officejet.show()' : // cannot override inherited member // 'LaserJet.show()' because it is sealed. override public void print() < Console.WriteLine("Officejet printer printing. "); >> // Driver Class class Program < // Driver Code static void Main(string[] args) < Printer p = new Printer(); p.show(); p.print(); Printer ls = new LaserJet(); ls.show(); ls.print(); Printer of = new Officejet(); of.show(); of.print(); >>
Вывод :
размер дисплея: 6 * 6 Печать на принтере . размер дисплея: 12 * 12 Печать на принтере LaserJet . размер дисплея: 12 * 12 Печать на принтере Officejet .
Объяснение: В приведенном выше коде C # класс Printer имеет блок отображения с размером 6 * 6, а класс LaserJet реализовал метод show , переопределив его так, чтобы он имел размер 12 * 12. Если какой-либо класс унаследует класс LaserJet , тогда он будет иметь такое же измерение 12 * 12 и не сможет реализовать собственное, т.е. он не может иметь 15 * 15, 16 * 16 или любые другие размеры. Таким образом, вызов LaserJet изолирует метод show , чтобы предотвратить его дальнейшее переопределение.
Для чего нужны изолированные классы и методы?
- Изолированный класс используется для прекращения наследования класса. Вы не можете наследовать или расширять какой-либо класс от него.
- Изолированный метод реализован таким образом, что никакой другой класс не может его переопределить и реализовать свой собственный метод.
- Основная цель изолированного класса — отобрать возможность наследования у пользователя, чтобы он не мог получить класс от изолированного класса. Изолированные классы лучше всего использовать, когда у вас есть класс со статическими членами.
например, классы “Pens” и “Brushes” пространства имен System.Drawing . Класс Pens представляет перья для стандартных цветов. Этот класс имеет только статические члены. Например, «Pens.Red» представляет собой перо красного цвета. Точно так же класс «Brushes» представляет стандартные кисти. «Brushes.Red» представляет собой кисть красного цвета.
sealed (C++/CLI и C++/CX)
sealed — это контекстно-зависимое ключевое слово для ссылочных классов, которое означает, что виртуальный элемент нельзя переопределить или что тип не может использоваться в качестве базового типа.
В стандарте языка ISO C++11 представлено ключевое слово final. Используйте final в стандартных классах, а sealed — в ссылочных классах.
Все среды выполнения
Синтаксис
ref class identifier sealed ; virtual return-type identifier() sealed ;
Параметры
идентификатор
Имя функции или класса.
return-type
Тип, который возвращается функцией.
Замечания
В первом примере синтаксиса запечатан (sealed) класс. Во втором примере запечатана виртуальная функция.
Используйте ключевое слово sealed для ссылочных классов и их виртуальных функций-членов. Дополнительные сведения см. в статье Спецификаторы переопределения и компиляция в машинный код.
Во время компиляции можно определить, запечатан ли тип, используя признак типа __is_sealed(type) . Дополнительные сведения см. в статье Compiler Support for Type Traits (C++/CLI and C++/CX) (Поддержка признаков типов компилятором (C++/CLI и C++/CX)).
sealed — контекстно-зависимое ключевое слово. Дополнительные сведения см. в статье Context-Sensitive Keywords (C++/CLI and C++/CX) (Контекстно-зависимые ключевые слова (C++/CLI и C++/CX)).
Среда выполнения Windows
Требования
Параметр компилятора: /ZW
Среда CLR
(Отсутствуют комментарии для этой возможности языка, которая применяется только в среде CLR).
Требования
Параметр компилятора: /clr
Примеры
В следующем примере кода показано влияние sealed на виртуальный элемент.
// sealed_keyword.cpp // compile with: /clr interface struct I1 < virtual void f(); virtual void g(); >; ref class X : I1 < public: virtual void f() < System::Console::WriteLine("X::f override of I1::f"); >virtual void g() sealed < System::Console::WriteLine("X::f override of I1::g"); >>; ref class Y : public X < public: virtual void f() override < System::Console::WriteLine("Y::f override of I1::f"); >/* // the following override generates a compiler error virtual void g() override < System::Console::WriteLine("Y::g override of I1::g"); >*/ >; int main() < I1 ^ MyI = gcnew X; MyI ->f(); MyI -> g(); I1 ^ MyI2 = gcnew Y; MyI2 -> f(); >
X::f override of I1::f X::f override of I1::g Y::f override of I1::f
В следующем примере кода показано, как пометить класс запечатанным.
// sealed_keyword_2.cpp // compile with: /clr interface struct I1 < virtual void f(); >; ref class X sealed : I1 < public: virtual void f() override <>>; ref class Y : public X < // C3246 base class X is sealed public: virtual void f() override <>>;