Запечатанный метод в C # - PullRequest
35 голосов
/ 11 ноября 2010

Я новичок в 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");
        }
    }


}

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

Ответы [ 6 ]

69 голосов
/ 11 ноября 2010

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

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

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

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

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

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

68 голосов
/ 11 ноября 2010

Что ж, вы тестируете только с двумя уровнями наследования, и вы не дошли до того, что «переопределяете» метод.Если вы сделаете три, вы увидите, что делает 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.
}
20 голосов
/ 11 ноября 2010

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

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

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.

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

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

1 голос
/ 05 октября 2016

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

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

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

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

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();
        }
    }
}
1 голос
/ 11 ноября 2010

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

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

0 голосов
/ 11 ноября 2010

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

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

...