是否可以将实例提升为派生类的实例?
例如,假设有一个基类Vehicle
。
Vehicle
派生了类:Boat
,Automobile
,Airplane
等...
创建类型为Vehicle
的新实例时,车辆类型未知
后来,人们发现车辆是什么,说它是Boat
。
是否可以将Vehicle
实例提升为Boat
对象?
澄清:Vehicle
实例可能已设置内容,并且提升的对象需要保留这些内容
P.S。我现在成功地做到了这一点,但是手工而且非常笨重。所以,我想知道是否有一种普遍接受的,规范的方式。
(2017年9月24日)Eric Lippert在下面的每个问题中添加了真实案例:
*我的整个C#体验都是自学成才的,所以我没有学术基础,也不了解"模式"等等。工厂模式和复合模式的想法听起来很有趣,可能是解决问题的更好方法(需要研究)。
我的真实情况是,我使用共享总线架构连接到计算机的测量设备(外围设备)自动进行电子测量。在任何给定的测试平台上,可以根据用户的选择连接各种不同的外围设备。为了自动确定哪些外设可用,我执行一个本地发现过程,找到每个连接外设的总线地址。然后,为了与发现的未知类型的外围设备通信,我创建了一个基类的实例,我调用Device
。 Device
具有某些基本的I / O协议方法和属性,例如总线地址,通信超时等。使用Device
然后查询外围设备的身份,找出制造商,型号和序列号。
根据这些信息,我确定了外围设备的类型,并希望"促进" Device
的实例,专门用于该外围类型的派生类的实例,例如SpectrumAnalyzer
或Oscilloscope
或其他任何内容。
我认为我在无意中所做的是在工厂类和基类之间创建一个交叉。知道外围设备的类型后,Device
有一个方法可以创建派生类的新实例,并将自己的属性深度复制到该派生实例。
也许如果我在工厂模式方面重新考虑解决方案而不是基类,我可以改进逻辑。
有趣的东西......谢谢你。*
答案 0 :(得分:7)
是否可以将Vehicle对象提升为Boat对象?
不。理想情况下,Vehicle将是一个抽象基类,因此首先不会出现仅仅是车辆的情况。
我现在成功地做到了这一点,但是却手工而且非常笨重。所以,我想知道是否有一种普遍接受的,规范的方式。
不。
当一个新类型的对象" Vehicle"创建的车辆类型未知
我发现很难想象你的程序会创建对象但直到后来才知道创建了什么类型的对象的场景。你能给出一个更现实的场景吗?对于您想要表达的内容,可能有更好的设计模式。
真实情况是我有远程外围设备,我发现存在并为其创建通信协议。只有这样,我才能发现外围设备的类型并创建一个“推广”的外围设备。对象
听起来你是以一种非常奇怪的方式使用工厂模式。工厂模式是创建"工厂对象"的模式,它知道如何构建特定类型的对象。您的车辆基础类充当车辆工厂,而不是车辆。你不能开车厂;它不是车辆。
答案 1 :(得分:1)
我认为在这种情况下正确的方法是在基本设备类型中有一个工厂方法,它将发现附加的外围设备并返回设备列表。设备是在发现过程中创建的派生类的具体实例。在第一遍中创建基础对象然后在secont传递中将其转换为派生实例并不是一个好的设计。尝试仅使用一次通过来完成工作。您可以为工厂使用一种静态方法:
static List<Device> Discover() {
return concrete instance;
}