多继承和C#
比方说,我有两个基本的抽象类,具有完全不同的功能:笔记本电脑和智能手机。 (假设功能完全不同)。而在我目前的项目中,我已经有许多笔记本电脑和智能手机的实施,而且他们总是完全不同。多继承和C#
但突然间,我收到一个要求添加一个pc-tablet实现的类,实际上它具有智能手机和笔记本电脑的功能。现在改变基础类已经太晚了,实际上我非常肯定这款pc平板电脑只会出现一次。
问题是,我应该能够在智能手机的conainer中容纳我的pc-tablet,但它也应该是笔记本电脑,因为继承的功能(实际上除此之外,在项目pc-tablet的某些部分仅用于笔记本电脑,并不需要智能手机的功能,而且将PC平板电脑视为该项目特定部分的智能手机也不好)。所以我有PcTabletAsLaptop:笔记本电脑类,这实际上是一台笔记本电脑,而不是智能手机。
我的解决办法是增加一个包装:
class PcTablet : SmartPhone
{
private PcTabletAsLaptop _pcTablet;
// Here goes all the methods of PcTabletAsLaptop as proxies:
public void Call(int number)
{
_pcTablet.Call(number);
}
// .....
}
有200+的方法,我想从PcTabletAsLaptop自动生成它们。
该解决方案看起来相当复杂。我的问题是好的,或者有一些简单的方法可以做到这一点?
如果您需要多重继承 - 在大多数情况下您做错了某些事情或尝试以错误的方式解决问题。层次结构如下所示?
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;
}
您的解决方案看起来像我的,因为只有我从智能手机派生PcTablet。我想你的解决方案可能会更好。但是我仍然需要对这200多种方法进行代理,以便PcTablet调用其中一个字段。所以,我的问题是它应该如何? – Archeg
因此,对于PcTablet类,笔记本电脑和智能手机类的公共API是不够的,您需要访问受保护的/专用的界面?如果可以,请在您需要访问笔记本电脑/智能手机的私人/受保护的界面时带上其中一个示例? – sll
我的意思是PcTabletAsSmartphone有Call()方法,在这种情况下PcTablet也应该有Call()方法,它调用asSmartphone.Call()。我有200多种这样的方法。当我隐藏PcTabletAsSmartphone时,我需要将此方法编写为隐藏内部实例的代理。当然,我可以将其作为智能手机实例公开,但这会打破所有设计 – Archeg
您可以提取的接口形式既智能手机&笔记本电脑,然后创建第三个界面PcTablet将来自前两个继承。这样,您就可以将PcTablet用作智能手机或笔记本电脑。
编辑:
为了能够重用逻辑每个智能手机&笔记本电脑里面,你可以使用适配器模式使PcTablet应该像这样的事情:
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()
}
}
你当然必须在构造函数中创建一个智能手机和laptopn,但它应该做的伎俩!通过这种方式,您可以重复使用智能手机中的代码,但也可以在不提供正确的情况下覆盖其行为。
你不能添加更多的基类“MobileDevice”,并让它们都继承它吗? –
200多种方法?也许是时候考虑一些重新设计。 –
@DaveBish我不想改变原始层次,因为该项目已经投入生产。实际上,这是客户的要求(我们正在编写框架,因此代码设计也被视为需求的一部分) – Archeg