Запечатывание интерфейса после его реализации - PullRequest
7 голосов
/ 22 марта 2011

Я работаю над небольшим проектом и столкнулся с этой проблемой.

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

public interface ITest
{
    void SomeMethod();
}

class A : ITest
{
    public sealed override SomeMethod()
    {

    }
}

Идея состоит в том, чтобы интерфейс был доступен каждому и имел какой-то специализированный класс, который его реализует.Исключением является то, что я хочу убедиться, что если кто-то создаст специализированный класс типа А., он / она не сможет изменить поведение метода.

Проблема в том, что вы не можете поставить "переопределите ключевое слово "там", так как метод не объявлен как "виртуальный" в интерфейсе.И вы не можете объявить его как «виртуальный» в интерфейсе, так как это запрещено.И вы не можете удалить ключевое слово «переопределить», так как оно необходимо для «запечатанного».

Любая обходная идея или метод мозгового штурма приветствуются, но если кто-то может предложить решение, которое включает интерфейс, я 'буду очень рад узнать это!

Спасибо!

РЕДАКТИРОВАТЬ: Забудьте этот вопрос!Как сказала Ани, я забыл, что по умолчанию метод в C # запечатан.Кажется, что всегда хорошо возвращаться к основам время от времени ...

Ответы [ 5 ]

22 голосов
/ 22 марта 2011

Я, возможно, совершенно неправильно понял вопрос, но если вы хотите запечатать метод в A, вы можете просто сделать:

class A : ITest
{
    public void SomeMethod()  { ... }
}

В отличие от Java, методы в C # по умолчанию закрыты . Подклассы A не смогут переопределить метод, так как он не был помечен virtual.

С другой стороны, если вы намерены пометить метод как «почти запечатанный» в интерфейсе, чтобы он заставил реализующий класс немедленно его запечатать, это невозможно. Это не (и не должно быть) дело интерфейса диктовать такие детали реализации - интерфейс предназначен для представления спецификации .

3 голосов
/ 22 марта 2011

Используйте абстрактный базовый класс с внутренней видимостью. Этот базовый класс не виден за пределами библиотеки, но позволяет запечатать метод, а класс по-прежнему реализует интерфейс.

public interface ITest
{
    void SomeMethod();
}

internal abstract class SuperA : ITest
{

    public abstract void SomeMethod();

}

class A : SuperA
{
    public sealed override void SomeMethod()
    {

    }
}
2 голосов
/ 22 марта 2011

Ваше понимание ключевого слова sealed неверно.В качестве модификатора метода sealed используется для предотвращения переопределения метода virtual (определенного в базовом классе) в следующем поколении производных классов.Например:

class Base
{
   public virtual void M() { }
}

class Derived : Base
{
   public sealed override void M() { }
}

class A : Derived
{
   public override void M() { } //compile error, M is sealed in Derived
}

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

если кто-то создаст специализированный класс типа A, он / она не сможет изменить поведение метода.

Если «специализированный класс» означает класс, производный от A, ответ будет: он всегда может скрыть метод в A, но не может изменить поведение метода.

1 голос
/ 22 марта 2011

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

Не проверял, но это должно работать?

public abstract class Test
{
    public virtual void SomeMethod() {}
    //OR
    public abstract void SomeMethod();//MSDN says:
    //an abstract method is implicitly virtual
}

class A : Test
{
    public sealed override SomeMethod()
    {

    }
}
0 голосов
/ 22 марта 2011

Методы в C # запечатаны по умолчанию. Вот пример

class Program
{
    static void Main(string[] args)
    {

        A obj = new A();
        obj.SomeMethod();
        b ss = new b();
        ss.SomeMethod();
        Console.ReadLine();
    }
}

public interface ITest { void SomeMethod(); }

class A : ITest { public void SomeMethod() {

    Console.WriteLine("SomeMethod Called from Class A object");
} }

class b : A
{
    //public override void SomeMethod()
    //{
    //    Console.WriteLine("Called from Class B Object");
    //}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...