多重继承

本文关键字:多重继承 | 更新日期: 2023-09-27 18:24:42

我在网上寻找可以帮助我解决困扰我的设计问题的信息。我对复杂的继承情况很陌生,所以我的解决方案实际上可以植根于更好的设计。但在试图弄清楚我的设计应该是什么的过程中,我一直认为我真的只需要继承一个以上的基类。

我的具体案例涉及资产和不同类型的资产。

资产开始。。。

每个物理设备都是资产
每个虚拟设备都是资产
每个服务器都是资产

每个PhysicalServer都需要既是PhysicalDevice又是服务器
每个VirtualServer都需要既是虚拟设备又是服务器
每个NetDevice都是PhysicalDevice
每个StorageArray都是PhysicalDevice

我想有一个解决方案是为PhysicalServersVirtualServers制Server代码。然而,我觉得这与我试图做的事情背道而驰,那就是继承。

它们需要是独立的类,因为每个类型都有属性和方法。例如,Server将具有OSCaption、Memory、Procs等。PhysicalDevice具有Location、Serial、Vendor等。而VirtualDevice将具有ParentDevice、State、VHDLocation等。

如果继承是线性的,那么我会遇到无法准确描述这些类型的问题。

界面似乎很有趣。似乎我可以将所有基类定义为接口,并根据需要在我的主类中实现它们。但是,我只是不确定如果我这样做会有什么影响。

例如,类似物理服务器IAsset

我陷入了困境,所以我真的只是在寻求建议或指导。

多重继承

接口是确保跨类型合同完整性的合适方法,但每个实现可能会出现重复的代码。

您的场景可能更适合组合,而不是继承(或其组合)。

示例-继承+组合

public class PhysicalServer : Asset
{
    public PhysicalInfo PhysicalProperties
    {
         get;
         set;
    }
}
public class VirtualServer : Asset
{
    public VirtualInfo VirtualProperties
    {
         get;
         set;
    }
}

示例-仅成分

public class VirtualServer
{
    public VirtualInfo VirtualProperties
    {
         get;
         set;
    }
    public AssetInfo AssetProperties
    {
         get;
         set;
    }
}

然后,您可以将多态性/泛型添加到组合中,并创建类型的衍生物来表示更具体的需求。

示例-继承+组合+从通用类型继承的泛型成员

public class VirtualServer<TVirtualInfo> : Asset
   where TVirtualInfo : VirtualDeviceInfo
{
    public TVirtualInfo VirtualProperties
    {
         get;
         set;
    }
}
public class VirtualServerInfo : VirtualDeviceInfo
{
   // properties which are specific to virtual servers, not just devices
}

有无数种方法可以对此进行建模,但有了接口、组合、继承和泛型,你就可以创建一个有效的数据模型。

使用mixin。

您首先要决定哪个是您希望对象成为的主要对象。在您的情况下,我认为它应该是服务器。

public class PhysicalServer : Server

然后添加其他功能的接口。

public class PhysicalServer : Server,IAsset,IVirtualDevice

并且将扩展方法添加到接口中。

public static int WordCount(this IAsset asset)
{
  //do something on the asset
}

下面是一篇关于mixin的文章,以防我的答案太简单:http://www.zorched.net/2008/01/03/implementing-mixins-with-c-extension-methods/

C#不支持从类的多重继承(但支持接口的多重实现)。

你所要求的不是多重继承。多重继承是指单个类具有多个基类。在您的示例中,每个类都继承自一个/零个其他类资产和服务器是最终基类。因此,在c#中这样做没有问题,您只需定义服务器中常见的功能,然后在虚拟设备物理设备

然而,您最终会得到一个可能复杂的类层次结构,许多人会主张组合而不是继承

。在这里,接口定义行为,类实现接口,表示它们做了一些事情,但每个类可以以不同的方式实现接口方法。因此,可以鼓励您以PhysicalServer接口为例。

首先要记住,继承是您提到的那种问题的明显结果。每个类都有不止一种行为,每个人都陷入了这个陷阱。太冷了。你不是第一个也不是最后一个。

你需要稍微改变一下你的思维,以脱离常规。

你需要从未来"变化"的角度来看待它,而不是从层次结构的类图来看待它。类图可能不是分层的,相反,它需要表示"什么变化"answers"什么保持不变"。据我所见,未来你可能会定义一个移动设备,虚拟移动设备。

在您当前的类中,您似乎拥有Vendor、Serial等属性。这些可能在MobileDevice中也需要,对吧?因此,你需要修改你的思维,真正考虑行为,而不是有层次感的类。

重新思考,你正在走多重继承的轨道,这是非常危险和复杂的设计。这不是你思考过程的正确性问题。这是一个问题,在不久的将来,你对某个东西和某个领先的人进行编码,使其复杂化,无法修复。

java中没有多重继承,原因之一是为了确保您不会以分层的方式思考。

想想"工厂"(用于创建)、策略(用于通用功能/处理)。

编辑:

事实上,您还应该考虑以库的形式创建层,以便对处理的主要部分进行完全的抽象和控制。您打算对Asset/Device类执行的操作应该抽象到一个库中,该库可以通过更改进行保护。