Как использовать (в чем смысл) sealed?

Вот документация
https://docs.microsoft.com/ru-ru/dotnet/csharp/lan...

Вот пример из документации
class A {}
sealed class B : A {}

То есть от класса 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 {field_1 = value;} }
 }

 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 {field_1 = value;} } //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? Почему запечатывание свойства я могу применить только ко второму классу?
  • Вопрос задан
  • 8732 просмотра
Решения вопроса 1
Почему для запечатывания требуется override?

По тому что если метод не виртуальный (если у него нет модификатора virtual, override или abstract), то его и так нельзя переопределить.
По-умолчанию все методы не виртуальные
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@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.


Почему запечатывание свойства я могу применить только ко второму классу?

В общем-то, функционал наследования исчисляется по уровням наследования, и там он как раз первый, а не второй. Второй класс перед глазами это первый уровень наследования и он запечатывается.
Ответ написан
Комментировать
freeExec
@freeExec
Участник OpenStreetMap
Вместо sealed я могу использовать new и спокойно писать свою логику, не вникая, что там было у родителя.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы