views:

346

answers:

5

I am trying to use selective features of two classes into 3rd class. For example, I have Button1 class which creates a fancy button border and Button2 class which writes a the text in colorful format. Now these classes are provided to me by 3rd party vendors where i dont have access to the code. The classes are not sealed so i can inherit and both are derived from the base Button class.

Now my requirement is to create a third class named Button3 class which had the functionality of both making fancy border and colorful text. Ideally, i would have inherited from both classes and used the specific functions. This is not possible in C# as it doesnt have multiple inheritence.

I was reading, that interfaces help achieve results in this case. I would request someone to guide me how to use the specific functionality of two classes in one class.

A: 

You can't just take random parts of different classes and combine them, even if C# had multiple inheritance. The problem is that the methods you need from each only work when they live inside the class and work together with the other methods and private state in that class. If you try to mix and match methods from one class with another they won't be able to share their internal state. So the next thing you might try is to use containment and have two copies of the internal state, but that leads to problems trying to keep them synchronized. Plus now both classes want access to the paint methods, etc. Instead of working together, they will most likely fight each other and paint over each others changes. It's difficult to get this right.

What you need to do is to take the source code for one of the two Button classes and modify it using the source code of the other Button class as inspiration (it's unlikely you can use the code directly). If you don't have access to (or the legal right to use) the source code then I'm afraid that you can't do it this way.

Your remaining options are:

  • Contact the authors of Button1 requesting them to add the desired features from Button2.
  • Contact the authors of Button2 requesting them to add the desired features from Button1.
  • Write a new button class yourself.
Mark Byers
A: 

Interface just defines the method signature, but not the method body. Meaning that you still can't get the behavior in Button1 and Button2 even if you use interface.

You can ask your vendor to do the following:

  1. Create interfaces that takes define the necessary properties for fancy button border and colorful text
  2. Create methods that draw the fanciful button border and write the text in colorful format by taking in the interface defined above.

Then you inherit your button3 from both of the interfaces, call the above methods to do whatever that needs to be done.

Ngu Soon Hui
A: 

In my opinion composition in combination with inheritance works when you want to simulate multiple inheritance. However when working with controls this usually not an option because you usually a control within another control. Some options that you could look into would be

User Controls - If you are using winforms Nested Controls - If you are using WPF.

FernandoZ
+1  A: 

As others have said, if your application does truly need to inherit from the two UI classes given then you won't be able to do this.

More generally than with a UI, here's a to think about this:

  • Full inheritance implies an "is-a" kind of relationship. Your buttons with fancy borders are buttons, but they can't be buttons with fancy text.

  • Interfaces define a "has-a" relationship. Here you have the "ability to set a fancy border on a button" and an "ability to set fancy text on a button". In those terms there's nothing to stop you applying both "abilities" to the same button class.

So an interface lets you do aggregation. Consider two classes DoerOfThis: IThis and DoerOfThat: IThat. To create a third class Something that does both DoThis and DoThat, aggregate:

public class Something : IThis, IThat
{
  public This DoerOfThis { set; }
  public That DoerOfThat { set; }

  public void DoThis()
  {
     DoerOfThis.DoThis();
  }

  public void DoThat()
  {
     DoerOfThat.DoThat();
  }
}
Jeremy McGee
A: 

Try to use Abstract Factory Pattern.

JMSA