Как подклассы могут иметь общее поведение, если он уже является производным от другого базового класса? - PullRequest
6 голосов
/ 18 февраля 2011

У меня есть два класса, которые реализуют ISomeBehavior.Теперь я хочу, чтобы они поделились функциональностью.Обычно я бы заменил ISomeBehavior на абстрактный класс, например SomeBehaviorBase.Проблема в том, что один из подклассов уже является производным от другого класса, и этот другой класс не является программным обеспечением, которым мы владеем.(Это C #, поэтому множественное наследование не вариант.) Подкласс, производный от стороннего класса, не имеет реализации.Он просто наследуется от стороннего класса и реализует ISomeBehavior, поэтому сторонний класс можно обрабатывать так же, как и другие подклассы, реализующие ISomeBehavior.

На данный момент я реализовал реализациюметод расширения на ISomeBehavior.Теперь код потребления может вызывать метод.Проблема с этим подходом состоит в том, что я хочу заставить вызывающий код использовать этот метод расширения.Я не могу удалить SomeMethod () из интерфейса, потому что метод расширения должен в конечном итоге вызывать его.

Любые идеи о том, как сделать так, чтобы два класса элегантно имели одинаковое поведение, когда один из них уже наследуется от другого, третье лицо, класс?Примечание: шаблон разработки стратегии звучит так, как здесь имеет смысл, но этот шаблон используется, когда поведение изменяется среди подклассов.Поведение здесь не меняется;им просто нужно поделиться.

Ответы [ 4 ]

5 голосов
/ 18 февраля 2011

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

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

2 голосов
/ 18 февраля 2011

Вот хорошая статья на эту тему: http://www.codeproject.com/KB/architecture/smip.aspx

ГДж

0 голосов
/ 18 февраля 2011

Как примерно так:

class MyClass: ThirdPartyClass
{
}

class MyFunctionality
{
     public MyFunctionality(ThirdPartyClass target)
   ...
}

interface IMyFunctionality
{
    public MyFunctionality MyFunctionality;
}

Таким образом, интерфейс будет обеспечивать, что производный класс должен создавать экземпляр добавочного члена, а конструкция MyFunctionality будет работать только со ссылкой на базуучебный класс.Это может не сработать, если есть защищенные участники, к которым вам нужен внутренний доступ.

0 голосов
/ 18 февраля 2011
    public interface ISomeBehavior
    {
        int Sample();
    }

    public class A : ISomeBehavior
    {
        int ISomeBehavior.Sample()
        {
            return 1;
        }
    }

   static class SomeExtension
   {
       public static int Sample(this ISomeBehavior obj)
       {
           return 2;
       }
   }

и затем используйте это

  A a = new A();
  var a1 = ((ISomeBehavior)a).Sample();    // a1 = 1
  var a2 = a.Sample();                     // a2 = 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...