2016-04-06 1 views
0

В целях простоты, скажем, у меня есть «базовый» абстрактный класс:Как избежать реализации методов из абстрактного класса?

public abstract class BaseClass 
{ 
    public abstract void BaseMethod(object obj); 

    public abstract void BaseMethod(); 
} 

Я хочу сделать 2-й и 3-й класс наследует от этого «BaseClass»:

public class Class1 : BaseClass 
{ 
    public override void BaseMethod(object obj) 
    { 
     //Some code 
    } 
} 

public class Class2 : BaseClass 
{ 
    public override void BaseMethod() 
    { 
     //Some code 
    } 
} 

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

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

абстрактные классы могут наследоваться без реализации абстрактных методов (хотя такой производный класс является абстрактным сам)

Is это утверждение неверно? Любые материалы по этой теме глубоко оценены. Благодаря!

+2

Почему вы хотите это сделать? Какую проблему ты пытаешься решить? – NWard

+0

«*** (хотя такой производный класс является абстрактным) ***« Попытка предотвратить выполнение дочерним классом или переопределения определенного метода базового класса - это бесполезное упражнение. Просто выходите на улицу и бить головой о тротуар, если хотите сделать себя несчастным. – Will

+0

Эти классы были бы прекрасны, если вы сделаете их «абстрактными». Конечно, любой класс, который вытекает из них, который не является также «абстрактным», должен был бы реализовать другой метод. Может быть, вы могли бы объяснить, почему вы думаете, что вам нужно это сделать, и мы можем предложить другой подход. Возможно, вам действительно нужны два отдельных интерфейса, каждый из которых определяет эти методы. – juharr

ответ

8

Абстрактные классы могут быть унаследованы без реализации абстрактных методов (хотя такой производный класс является абстрактным сам)

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

+0

У вас есть опечатка - вы много писали, а не обязаны. –

+0

@ZoharPeled Спасибо, исправлено. –

+0

Большое спасибо за ввод, я боролся с этой последней частью заявления. – Xanagandr

1

«Абстрактные классы могут быть наследованы без реализации абстрактных методов (хотя такой производный класс является абстрактным)».

Это утверждение верно. Это означает, что классы Class1 и Class2 также должны быть абстрактными, если они не реализуют все абстрактные методы.

2

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

public abstract class Class1 : BaseClass 
{ 
    public override void BaseMethod(object obj) 
    { 
     //Some code 
    } 
} 

public abstract class Class2 : BaseClass 
{ 
    public override void BaseMethod() 
    { 
     //Some code 
    } 
} 

Таким образом, вы по-прежнему не будет иметь возможность создавать классы. Лучшим решением было бы сделать виртуальные функции вместо абстрактных с пустым телом или телом, которое порождает ошибку.

public abstract class BaseClass 
{ 
    public virtual void BaseMethod(object obj) { throw new NotImplmentedException(); } 

    public abstract void BaseMethod() { throw new NotImplmentedException(); } 
} 

Но я до сих пор считаю, что это плохая идея, если у вас есть List<BaseClass>, как вы будете знать, что правильный вариант вы хотите позвонить? Вы должны подумать, что ваш дизайн имеет только один виртуальный метод, который могут использовать обе функции.

1

Как уже говорилось другими, вы не можете. Вы должны разделить свой BaseClass в двух разных классах (если BaseClass принадлежит вам).

ИЛИ

можно «обмануть», обернув или, как в данном примере, расширяя BaseClass определенным образом

public class BaseClassWrapper : BaseClass 
    { 
     private IBaseMethodA methodA; 

     private IBaseMethodB methodB; 

     public BaseClassWrapper(IBaseMethodA methodA, IBaseMethodB methodB) 
     { 
      this.methodA = methodA; 
      this.methodB = methodB; 
     } 

     public override void BaseMethod() 
     { 
      methodB.BaseMethod(); 
     } 

     public override void BaseMethod(object obj) 
     { 
      methodA.BaseMethod(obj); 
     } 

     public interface IBaseMethodA 
     { 
      void BaseMethod(object obj); 
     } 

     public interface IBaseMethodB 
     { 
      void BaseMethod(); 
     } 
    } 

Теперь у вас есть два отдельных интерфейса для реализации. Это явно делает дизайн и реализацию более сложными, но может дать вам некоторые преимущества. Например, если у вас есть 4 различных варианта реализации для IBaseMethodA и 3 для IBaseMethodB, вы можете смешивать и сопоставлять их.