2011-03-22 3 views
7

Я работаю над небольшим проектом, и я столкнулся с этой проблемой.Уплотнение интерфейса после его реализации

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

public interface ITest 
{ 
    void SomeMethod(); 
} 

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

    } 
} 

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

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

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

Спасибо!

EDIT: Забудьте об этом вопросе! Как сказал Ани, я забыл, что по умолчанию метод в C# запечатан. Похоже, это всегда хорошо, чтобы вернуться к основам один раз в то время ...

ответ

21

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

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

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

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

+3

+1 Дои! просто. Не думал об этом! – gideon

+1

Ахаха так просто, пренебрегайте моим глупым ответом: P –

+4

+1 для обнаружения потерянного java dev –

1

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

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

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

Потому что я хотел иметь интерфейс, если это возможно. Но да, это также способ достижения этого. –

3

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

public interface ITest 
{ 
    void SomeMethod(); 
} 

internal abstract class SuperA : ITest 
{ 

    public abstract void SomeMethod(); 

} 

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

    } 
} 
2

Ваше понимание ключевого слова 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, но он не может изменить поведение метода.

+0

Мое понимание было верным, я просто забыл, что публичный метод закрыт по умолчанию, как ответил Ани. –

0

методы в 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"); 
    //} 
} 
Смежные вопросы