1

是否可以将实例提升为派生类的实例?

例如,假设有一个基类VehicleVehicle有派生类:Boat, Automobile, Airplane, 等等...

当创建一个新的 type 实例时Vehicle,车辆的类型是未知的。
后来才发现这辆车是什么,说是一辆Boat。是否可以将Vehicle实例提升为Boat对象?

澄清:Vehicle实例可能有内容集,并且提升的对象需要保持这些内容

PS我现在已经成功地做到了,但是是手动的,而且非常笨拙。所以,我想知道是否有一种普遍接受的规范方式。

(2017 年 9 月 24 日)在下面添加了 Eric Lippert 的每个问题的真实案例:

*我的整个 C# 经验都是自学的,所以我没有学术基础,对“模式”等也不太了解。工厂模式和复合模式的想法听起来很有趣,可能是解决问题的更好方法(需要研究)。

我的真实案例是,我使用使用共享总线架构连接到计算机的测量设备(外围设备)自动进行电子测量。在任何给定的测试台上,用户可以选择连接各种不同的外围设备。为了自动找出可用的外围设备,我执行了一个自行开发的发现过程,以查找每个连接的外围设备的总线地址。然后,为了与发现的未知类型的外围设备进行通信,我创建了一个我调用的基类的实例DeviceDevice具有一定的基本 I/O 协议方法和属性,如总线地址、通信超时等。然后使用Device我查询外围设备的身份以找出制造商、型号和序列号。

从该信息中,我确定了外围设备的类型,并希望将实例“提升”为Device专门针对该外围设备类型的派生类的实例,例如SpectrumAnalyzerOscilloscope或其他。

我认为我无意中所做的是在工厂类和基类之间创建了一个排序交叉。一旦知道外围设备的类型,Device就有一个方法可以创建派生类的新实例并将其自己的属性深度复制到该派生实例。

也许如果我根据工厂模式而不是作为基类重新考虑解决方案,我可以改进逻辑。

有趣的东西......谢谢你。*

4

2 回答 2

7

是否可以将 Vehicle 对象提升为 Boat 对象?

没有。理想情况下,Vehicle 将是一个抽象基类,因此一开始就不会有 just-a-Vehicle 的实例。

我现在成功地做到了这一点,但是手工操作而且非常笨拙。所以,我想知道是否有一种普遍接受的规范方式。

没有。

当创建“车辆”类型的新对象时,车辆的类型是未知的

我发现很难想象您的程序将创建对象但直到后来才知道创建了哪种对象的场景。你能给出一个更真实的场景吗?对于您想要表示的内容,可能有更好的设计模式。

实际情况是我发现了远程外围设备并为其创建了通信协议。只有这样我才能发现外围设备的类型并创建一个“提升”对象

听起来您正在以一种非常奇怪的方式使用工厂模式。工厂模式是创建“工厂对象”的模式,它知道如何构建特定类型的对象。您的 Vehicle 基类充当车辆工厂,而不是车辆。你不能开汽车厂;它不是一辆车。

于 2017-09-23T15:28:54.200 回答
1

我认为在这种情况下正确的方法是在基本设备类型中有一个工厂方法,它将发现连接的外围设备并返回设备列表。设备是派生类的具体实例,在发现过程中创建。在第一遍中创建基础对象然后在第二遍中将其转换为派生实例不是一个好的设计。尝试只使用一次完成这项工作。您可以对工厂使用一种静态方法:

static List<Device> Discover() { return concrete instance; }

于 2017-09-24T20:54:44.910 回答