How can subclasses share behavior when one already

2019-06-19 19:02发布

问题:

I have two classes that implement ISomeBehavior. Now I want them to share functionality. Normally I would replace ISomeBehavior with an abstract class, like SomeBehaviorBase. The problem is that one of the subclasses already derives from another class, and that other class isn’t software we own. (This is C#, so multiple inheritance isn't an option.) The subclass, that derives from the 3rd party class, has no implementation. It simply derives from the 3rd party class, and implements ISomeBehavior, so the 3rd party class can be treated the same way as the other subclasses that implement ISomeBehavior.

What I've done, for the moment, is implement an extension method on ISomeBehavior. Now the consuming code can call the method. The problem with that approach is that I want to force the calling code to use this extension method. I can't remove SomeMethod() from the interface, because the extension method has to eventually call it.

Any ideas on how to let two classes elegantly share the same behavior, when one of them already derives from another, third party, class? Note: The strategy design pattern sounds like it makes sense here, but that pattern is used when behavior varies among subclasses. The behavior here doesn't vary; it just needs to be shared.

回答1:

Is there any reason you can't use composition instead of delegation to implement the class which currently derives from the 3rd party class? Just delegate all the interface methods to an instance of the third party class. That way, if you want to add functionality you can use a common base class.

This won't work in some cases where the object identity is relevant, but in many cases it's a perfectly reasonable design.



回答2:

Here's a good article on this subject: http://www.codeproject.com/KB/architecture/smip.aspx

GJ



回答3:

    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;
       }
   }

and then use this

  A a = new A();
  var a1 = ((ISomeBehavior)a).Sample();    // a1 = 1
  var a2 = a.Sample();                     // a2 = 2


回答4:

How about something like this:

class MyClass: ThirdPartyClass
{
}

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

interface IMyFunctionality
{
    public MyFunctionality MyFunctionality;
}

So the interface would enforce that the derived class has to instantiate the add-on member, and the design of MyFunctionality would just operate against a reference to the base class. This might not work if there are protected members that you need internal access to, though.