2010-11-11 2 views
26

Я новичок в C#. Я читаю о запечатанном ключевом слове. У меня есть опечатанный класс. Я прочитал строку о методе Sealed, где мы можем сделать метод Sealed. Линия была (By объявляя метод как запечатанный, мы можем избежать дальнейшего переопределения этого метода.) Я создал демоверсию, но не понял, что используется значение вышеприведенной линии и метода герметизации. Ниже мой код: -Запечатанный метод в C#

using System; 

namespace ConsoleApplication2 
{ 
    class Program:MyClass 
    { 
     public override sealed void Test() 
     { 
      Console.WriteLine("My class Program"); 
     } 
     static void Main(string[] args) 
     { 
      Program obj = new Program(); 
      obj.Test(); 
      Console.ReadLine(); 
     } 
    } 

    class MyClass 
    { 
     public virtual void Test() 
     { 
      Console.WriteLine("My class Test"); 
     } 
    } 


} 

Скажите, пожалуйста, почему мы используем Запечатанные методы и каковы преимущества герметичных методов.

ответ

48

Ну, вы тестируете только два уровня наследования, и вы не понимаете, что вы «еще более переопределяете» метод , Если вы сделаете это три, вы можете увидеть, что делает sealed:

class Base { 
    public virtual void Test() { ... } 
} 
class Subclass1 : Base { 
    public sealed override void Test() { ... } 
} 
class Subclass2 : Subclass1 { 
    public override void Test() { ... } // Does not compile! 
    // If `Subclass1.Test` was not sealed, it would've compiled correctly. 
} 
+0

Спасибо Mehrdad .. :) –

+0

Могу ли я сделать это с первым уровнем, являющимся интерфейсом? –

-3

У C# есть это, потому что Java имеет идентичную функцию (final методов). Я никогда не видел законного использования.

Если вы не хотите разрешать расширение, весь класс должен быть помечен sealed, а не только одним методом.

+6

C# имеет, потому что Java имеет это? Я так не думаю. Более вероятным объяснением является то, что у C# и Java есть функция, потому что это полезная функция. –

+2

@ Эрик: Конечно, если бы мы говорили о ковариации массива, это было бы другое дело;) –

+0

@ Джон: действительно, хотя, конечно, цепочка дизайнерских решений там немного менее прямая. Я бы сказал, что система CLR типа имеет эту функцию, потому что язык Java делает, а C# имеет эту функцию, потому что у нее есть система CLR. –

18

Ну, вы использовали бы только «запечатанный» метод , если бы вы не хотели, чтобы производные классы дополнительно переопределяли ваш метод. Методы запечатываются по умолчанию, если они не объявлены как виртуальные, а не переопределяют другой виртуальный метод. (В Java методы являются виртуальными по умолчанию - для достижения «по умолчанию» поведения C# вы должны пометить метод как final.)

Лично мне нравится контролировать наследование тщательно - я предпочитаю, чтобы все классы были закрыты, если это возможно. Однако в некоторых случаях вы все же хотите разрешить наследование, но убедитесь, что методы не переопределены. Одно использование может быть эффективным template the method, например. для диагностики:

public sealed override void Foo(int x) 
{ 
    Log("Foo called with argument: {0}", x); 
    FooImpl(x); 
    Log("Foo completed"); 
} 

protected abstract void FooImpl(int x); 

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

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

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

58

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

A Запечатанный метод в незапечатанном классе - метод, который нельзя переопределить в производном классе этого класса.

Почему мы используем герметичные методы? В чем преимущества запечатанных методов?

Хорошо, почему вы используете виртуальные методы? Чтобы указать точку, в которой поведение класса может быть настроено.Итак, почему вы используете запечатанные методы? Чтобы обеспечить то, в котором вам гарантировано, что никаких изменений в поведении какого-либо производного класса в отношении этого метода не произойдет.

Точки, где можно настроить поведение класса полезно но опасно. Они полезны, потому что они позволяют производным классам изменять поведение базового класса. Они опасны ... ждут этого ... , потому что они позволяют производным классам изменять поведение базового класса. Виртуальные методы в основном позволяют третьим лицам делать ваши классы crazy вещи, которые вы никогда не ожидали или не тестировали.

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

+0

Спасибо Эрик .. :) –

+0

+1 Спасибо, отличный ответ. – Sabuncu

+0

Спасибо @ Eric. Простое и точное объяснение. – Slan

1

Теперь, если вы объявляете подкласс программы, вы не сможете переопределить метод Test, это точка.

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

1

Запечатанные методы

Sealed метод используется для определения первостепенную уровня виртуального метода.

Запечатанное ключевое слово всегда используется с ключевым словом переопределения.

Практическая демонстрация запечатанном метода

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace sealed_method 
{ 
    class Program 
    { 
     public class BaseClass 
     { 

      public virtual void Display() 
      { 
       Console.WriteLine("Virtual method"); 
      } 
     } 

     public class DerivedClass : BaseClass 
     { 
      // Now the display method have been sealed and can;t be overridden 
      public override sealed void Display() 
      { 
       Console.WriteLine("Sealed method"); 
      } 
     } 

     //public class ThirdClass : DerivedClass 
     //{ 

     // public override void Display() 
     // { 
     //  Console.WriteLine("Here we try again to override display method which is not possible and will give error"); 
     // } 
     //} 

     static void Main(string[] args) 
     { 

      DerivedClass ob1 = new DerivedClass(); 
      ob1.Display(); 

      Console.ReadLine(); 
     } 
    } 
} 
Смежные вопросы