2015-04-21 1 views
6

Я хотел бы написать
класса X (это), который
наследует от (основания) может
выполнить методы B (?) И
должен реализовывать член от C (интерфейс).Есть ли что-то вроде класса, который может быть реализован?

Реализация A и C не является проблемой. Но поскольку X не может выводиться из нескольких классов, кажется, что X не наследует логику A и B. Обратите внимание, что A - очень важный базовый класс, а B - почти интерфейс, но содержит исполняемое поведение. Причина, по которой я не хочу, чтобы B был интерфейсом, заключается в том, что поведение одинаково для каждого класса, который наследует или реализует его.

Должен ли я действительно объявить B как интерфейс и реализовать те же самые 10 строк кода для каждого X, для которого требуется поведение B?


2 месяца
Я в настоящее время обучение C++ для использования в UE4 (Unreal Engine 4).
Поскольку C++ намного менее строг, чем C# это на самом деле содержит шаблона реализации IDOM термин, который описывает это поведение: Их называют Mixin s.

Вы можете прочитать абзац о смешивании C++ here на стр. 9 (второй абзац).

+2

Почему вы просто не наследуете B от A или наоборот? –

+3

Почему вы не можете использовать композицию здесь? Делегируйте методы B в экземпляр B ...(Очень сложно говорить об этом подобным образом таким абстрактным образом. Было бы более полезно, если бы вы дали конкретный пример.) –

+0

@ k4rlsson Поскольку не каждый X требует B (разработчик должен иметь возможность реализовать его или нет) –

ответ

5

действительно ли я должен объявить B в качестве интерфейса и реализовать те же 10 строк кода для каждого X, сколько нужно поведение B?

Да и нет. Вам нужно сделать интерфейс B. Но общие реализации методов не должны дублироваться во всех реализациях интерфейса. Вместо этого, они должны идти в расширение класса для интерфейса B:

public interface B { 
    void MethodX(); 
    void MethodY(); 
} 
public static class ExtensionsB { 
    public static void MethodZ(this B b) { 
     // Common implementations go here 
    } 
} 

Методы расширения предоставляют способ обмена реализации «по горизонтали», не имея ваши классы наследуют от второго класса. Методы расширения ведут себя так, как если бы они были обычными методами класса:

class X : A, B { 
    public void MethodX() {...} 
    public void MethodY() {...} 
} 
public static void Main(string[] args) { 
    var x = new X(); 
    x.SomeMethodFromA(); 
    x.MethodX(); // Calls method from X 
    x.MethodY(); // Calls method from X 
    x.MethodZ(); // Calls method from ExtensionsB 
} 
+0

Это замечательно! Я бы хотел, чтобы вы добавили атрибут class для вашего класса расширения. И я хочу отметить, что метод расширения можно вызвать из класса, используя this.Extension(). Вызов Extension() внутри класса не работает. –

1

Я думаю, что вам лучше всего будет требовать экземпляр B в конструкторе A, а затем выставить или вызывать методы B в соответствии с требованиями:

public class X : A, C 
{ 
    private readonly B _b; 

    public X(B b) 
    { 
     _b = b; 
    } 
} 

Вы найдете много информации о такого рода подход, если вы посмотрите Composition over inheritance

+0

Это заставит разработчика реализовать (объявить) B, но я хочу, чтобы разработчик разрешил самостоятельно выбирать (реализовывать). Как будто B - это интерфейс –

+0

Я не совсем уверен, что вы имеете в виду; реализация и объявление - это не одно и то же. Было бы проще рекомендовать решение, если вы дадите конкретный пример. Но композиция - довольно гибкий подход. – RagtimeWilly

+0

Извините, что не предоставил конкретный пример. Я имел в виду, что ваш X ВСЕГДА объявляет поле B. Но я хочу иметь возможность решить, использует ли мой X (реализует) B или нет. С ответом, предоставленным «dasblinkenlight», теперь я могу решить реализовать B на моем X или игнорировать его. Если я захочу проигнорировать его, на моем X не будет поля B. –

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

  • Нет связанных вопросов^_^