2009-06-23 5 views
5

Скажем, у меня есть следующий код:C# Наследование

interface ISomeInterface 
{ 
    void DoSomething(); 
    void A(); 
    void B();  
} 

public abstract class ASomeAbstractImpl : ISomeInterface 
{ 
    public abstract void A(); 
    public abstract void B(); 
    public void DoSomething() 
    { 
     // code here 
    } 
} 

public class SomeImpl : ASomeAbstractImpl 
{ 
    public override void A() 
    { 
     // code 
    } 

    public override void B() 
    { 
     // code 
    } 
} 

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

Возможно ли это?

ответ

9

Методы в C# по умолчанию закрыты. Существует, однако, ничего, что вы можете сделать, чтобы предотвратить скрытие метода (выставляя метод с тем же именем в производном классе, обычно с new).

Или, если на то пошло, интерфейс-переопределённой:

static void Main() 
{ 
    ISomeInterface si = new EvilClass(); 
    si.DoSomething(); // mwahahah 
} 

public class EvilClass : ASomeAbstractImpl, ISomeInterface 
{ 
    public override void A() {} 
    public override void B() { } 
    void ISomeInterface.DoSomething() 
    { 
     Console.WriteLine("mwahahah");    
    } 
} 
2

Все методы запечатаны по умолчанию, но нет никакого способа предотвратить Скрытие членов.

Компилятор C# выдаст предупреждение о компиляторе всякий раз, когда вы скрываете элемент, но кроме этого вы не можете его предотвратить.

+5

Если вы сделаете это случайно, оно выдаст предупреждение. добавьте «новый» квалификатор, и он закрывается ... –

0

Метод, который не помечен как virtual, по умолчанию закрыт. В производном классе вы должны пометить «переопределяющий» метод с ключевым словом new, иначе вы получите предупреждение о компиляторе. Если метод суперкласса помечен как виртуальный, вы можете его запечатать за запечатанным переопределением.

http://msdn.microsoft.com/en-us/library/aa645769(VS.71).aspx

0

, если SomeImpl класс содержит метод DoSemthing, это означает, что он скрывает оригинал не переопределить.

0

Имея дело с интерфейсами и абстрактными классами, это больше о том, что вы ДОЛЖНЫ делать, а не о том, что вы не можете сделать. Таким образом, вы можете позволить пользователю интерфейса знать, что это методы, которые они должны реализовать, и с вашими абстрактными классами вы можете использовать ключевое слово virtual, чтобы сообщить им об этом ОК, чтобы переопределить метод. Однако вы не можете помешать им делать слишком много. Даже если вы целенаправленно не используете ключевое слово virtual, они все равно могут скрыть его с помощью ключевого слова .

Смежные вопросы