How to reuse code when multiple inheritance is not an option?
Asked Answered
S

5

2

I would like to make use of few methods from couple of my old tested classes into my new class that I am building. Unfortunately, C# does not support multiple inheritance. How do I reuse code from these old classes? Do I just create them as member objects? or Do I have any other options?

Soapberry answered 29/7, 2009 at 20:56 Comment(5)
FORTUNATELY C# doesn't support multiple inheritance!Scrofula
You shouldn't use inheritance for code reuse in any language, whether or not MI is supported.Fractionate
@jalf: why not? inheritance is a powerful feature. My controversial opinion is: would it be nice if C# DID support Multiple Inheritance?Jailbird
@Scrofula a nice example for a programming language that allows code sharing without inheritance is Swift. It allows you to define two classes with protocols (interfaces) and write a “protocol extension” - an extenstion that defines implementation for an interface, and who ever add that interface to a class will get the implementation for free ;)Paramnesia
@jalf see my comment (I’m not allowed to tag two users in one comment, sorry)Paramnesia
D
13

Generally, using composition instead of inheritance is the way forward, yes. If you could give a concrete example of the kind of thing you mean, that would make it easier to help find the appropriate approach though: it's not always the same.

Dampen answered 29/7, 2009 at 20:59 Comment(0)
W
5

Using them as member objects should be a good idea. Then you can also expose only the methods of interest, and adapt them if necessary.

Whacking answered 29/7, 2009 at 20:59 Comment(1)
This is called the delegation pattern, though with delegates in .NET that might sound a little confusing.Roye
N
4

You can recreate then as extension methods when they work on the same type.

public static void MyMethod( this MyType target ){}


MyType.MyMethod()

as noted below, if you have a class which derives from MyType or more common implements the interface the extension method works on, the extension works for those.

public class MyDerived : MyType{}

MyDerived.MyMethod()
Nonconformist answered 29/7, 2009 at 21:0 Comment(2)
How would this help you to reuse code? You still have to define the extension method for your new class?Roye
But they may be defined for generic types or for a more general interface, allowing the same extension method to be reused across a large number of classes.Fractionate
S
2

Technically, C# implements multiple interface inheritence, but not multiple implementation inheritence.

The problem with multiple implementation inheritence is that it leads to situations like the diamond problem.

You can simulate multiple implementation inheritence using multiple interface inheritence and composition, which is close to what you described as creating the objects that you want to re-use "as member objects". What you don't want to do, however is expose unnecessary behaviour from your wrapped type.

Following is a class diagram showing the basic principle of multiple inheritence through composition:

Multiple Inheritance http://www.freeimagehosting.net/uploads/cb219cefba.jpg

The drawback of this is that any changes to the interface IBreeper will require corresponding changes to Breeper, and vice versa.

Taking a step back though - you need to carefully look at the reasons for composing the old classes. Is it to:

  1. Enhance or step up existing behaviour. You should then consider the Proxy Pattern;

  2. Create a "one stop shop" for all of your behaviour. You should really only be doing this if your SuperFuddler is cohesive (that is, all exposed behaviour is aligned), otherwise you'll be moving into a God Object situation which isn't conducive to being maintainable;

  3. Present an interface that is more consistent with a mode of use required by a certain class of clients of your SuperFuddler. In this case, you should consider the Adapter Pattern.

Supportive answered 30/7, 2009 at 6:51 Comment(0)
C
0

You can fake it pretty easily like this:

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();
Clypeus answered 29/7, 2009 at 21:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.