Reputation: 8462
Let's say I have two base abstract classes with completely different functionality: Laptop and Smartphone. (Suppose the functionality is completely different). And in my current project I had already many implementations of laptops and smartphones, and they always were completely different.
But suddenly I received a request to add a class that is an implementation of pc-tablet, that is actually have functions of both smartphone and laptop. It is too late to change the base classes, and actually I'm very sure that this pc-tablet will appear only once.
The problem is, I should be able to contain my pc-tablet in the conainer for smartphones, but it should also be laptop, because of the inherited functionality (actually beside that, in some part of the project pc-tablet is used only as laptop, and it doesn't need smartphone functionality. Moreover it is bad to look at pc-tablet as smartphone for that particular part of the project). So I have PcTabletAsLaptop : Laptop class, that is actually a laptop, and not a smartphone.
My solution is to add a wrapper:
class PcTablet : SmartPhone
{
private PcTabletAsLaptop _pcTablet;
// Here goes all the methods of PcTabletAsLaptop as proxies:
public void Call(int number)
{
_pcTablet.Call(number);
}
// .....
}
There are 200+ methods and I want them to be generated automatically from PcTabletAsLaptop.
This solution looks quite complicated. My question is it good, or maybe there are some simplier ways to do that?
Upvotes: 4
Views: 273
Reputation: 748
You could extract an interface form both SmartPhone & Laptop then create a third interface PcTablet that will inherit from the first two. That way, you will be able to use the PcTablet as an Smartphone or a Laptop.
Edit:
To be able to reuse the logic inside each SmartPhone & Laptop you could use the Adapter Pattern so PcTablet should look like something like that :
public class PcTablet :ISmartPhone, ILaptop
{
private SmartPhone _smartphone;
private Laptop _laptop;
public void ISmartPhone.Call()
{
_smartPhone.Call();
// OR IMPLEMENT THE RIGHT BEHAVIOR
//INSTEAD OF CALLING _smartPhone.Call()
}
}
Of course you will have to create a smartphone and the laptopn in the constructor but it should do the trick ! That ways, you'll be able to reuse code in Laptop & SmartPhone but also override their behavior in the case that they don't provide the right one.
Upvotes: 3
Reputation: 62484
If you need multiple inheritance - in most cases you are doing something wrong or trying to solve a problem in a wrong way. What about hierarchy like shown below?
internal class PcTabletAslaptop : LaptopBase
{
// here is you can expose / override laptop specific stuff
}
internal class PcTabletAsSmartphone : SmartphoneBase
{
// here is you can expose / override smartphone specific stuff
}
public interface IPcTablet
{
// just expose PcTablet specific API
}
public sealed class PcTablet : IPcTablet
{
private PcTabletAsSmartphone asSmartphone;
private PcTabletAsLaptop asLaptop;
}
Upvotes: 1
Reputation: 13150
I think you can think in terms of composition rather than aggregation.
What about SmartPhone
contains Tablet
.
Upvotes: 0