Как повторно использовать код, когда множественное наследование не вариант?

StackOverflow https://stackoverflow.com/questions/1202986

Вопрос

Я хотел бы использовать несколько методов из пары моих старых протестированных классов в мой новый класс, который я создаю. К сожалению, C # не поддерживает множественное наследование. Как я могу использовать код из этих старых классов? Я просто создаю их как объекты-члены? или у меня есть другие варианты?

Это было полезно?

Решение

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

Другие советы

Использование их в качестве объектов-членов должно быть хорошей идеей. Тогда вы также можете выставить только интересующие вас методы и адаптировать их при необходимости.

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

public static void MyMethod( this MyType target ){}


MyType.MyMethod()

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

public class MyDerived : MyType{}

MyDerived.MyMethod()

Технически, C # реализует множественное наследование interface , но не множественное реализация наследование.

Проблема с множественным наследованием реализации заключается в том, что это приводит к такие ситуации, как проблема с бриллиантами .

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

Ниже приведена диаграмма классов, показывающая основной принцип множественного наследование через композицию:

Множественное наследование http://www.freeimagehosting.net/uploads/cb219cefba.jpg

Недостатком этого является то, что любые изменения интерфейса IBreeper потребуют соответствующие изменения в Breeper, и наоборот.

Делая шаг назад - нужно внимательно изучить причины сочинять старые классы. Это чтобы:

<Ол>
  • Улучшение или усиление существующего поведения. Затем вы должны рассмотреть Шаблон прокси ;

  • Создать " единый магазин " за все ваше поведение. Вы действительно должны делать это только в том случае, если ваш SuperFuddler является связным (то есть все выставленное поведение выровнено), в противном случае вы перейдете в объект Бога , который не способствует возможности сопровождения;

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

  • Вы можете легко подделать его так:

    public interface IFoo {
        void DoFoo();
    }
    
    public class Foo : IFoo {
        public void DoFoo() { Console.Write("Foo"); }
    }
    
    public class Bar {
        public void DoBar() { Console.Write("Bar"); }
    }
    
    public class FooBar : IFoo, Bar {
        private IFoo baseFoo = new Foo();
        public void DoFoo() { baseFoo.DoFoo(); }
    }
    
    //...
    
    FooBar fooBar = new FooBar();
    
    fooBar.DoFoo();
    fooBar.DoBar();
    

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top