public class ClassA { public string FieldA = "Something first"; } public class ClassB : ClassA { public string FieldB = "Something second"; }
众所周知,ClassB的对象可以在需要ClassA的每个地方使用.例如,一种方法
public void DoSthWithObject(ClassA a);
可以像这样调用:
ClassB b = new ClassB(); DoSthWithObject(b);
也可以将继承类型转换为父类型:
ClassA a = (b as ClassA);
因此编译器/框架知道如何“使用”需要ClassA的ClassB数据.
而现在的问题是:是否有可能以某种方式反过来做?假设我有一个类型为ClassA的变量,我想开始将它作为ClassB使用,但同时保留ClassB从ClassA继承的所有字段并且不实例化新对象?据我所知,它需要扩展为ClassA对象分配的内存以容纳ClassB的字段.
简单地说,我想做这样的事情:
ClassA a = new ClassA(); ClassB b = (a as ClassB); // some magic happens here
(我知道我可以实现IConvertible并使用Convert或提供一些克隆机制,但我想避免这样的解决方案.)
编辑
由于答案似乎集中在提出替代解决方案或警告我甚至想要按我的意愿去做,我决定稍微改变我的问题并提出赏金,所以也许我可以得到更好的答案.
首先,我希望这与语言无关.
第二:我真的明白,不是每个工具都是锤子,我可以(我希望)区分杰克和简.我也不需要关于基本OOP的课程(除非有人能够证明我正在犯一个基本的概念错误,我现在显然不知道).我想知道的是,是否以及为什么自动的父到子类转换在逻辑上是不可能的,如果可能的话(并且从评论中可以看出有可能的语言)那么为什么它是危险/充满缺陷.它是如何在这些语言中实际上技术性地完成,“支持”它(或者至少不禁止它).
但我确实期待真正的编程实例,而不仅仅是隐喻.
只是为了说清楚:我不是在寻找关于向下传播先前升级对象的信息.这不是这种情况.
如果我是一个希望同时在同一个表栏上汇总和分组的人 – 请告诉我.我知道我很聪明,应该明白. :-)我只是不想留下这个问题,感觉OOP有一些基本的东西,我没有抓到.
注意
在David的回答中,我提到了花车,但实际上是指实数(数学术语).这是因为我的英语相当不完美.请停止挑选它. :]
谢谢
我要感谢大家的回答.我决定给史蒂夫一笔赏金,但这并不意味着我认为问题已经结束了.我仍在寻找反对自动对象转换的论据.我必须管理员,我感到有点失望,那些最警告我的人无法提供与转换有关的明确例子(与投票无关).
根据我自己的研究,我决定在一个单独的答案中注明一些事情(如果有人发现它们有用).请随时编辑和扩展列表.
这是特定语言的实现细节,而不是面向对象思维的固有限制.我可以想象许多场景需要这种行为 – 也许Shape是一个Rectangle,但我们决定将它改成Square(因为square是一种矩形).正如您所指出的那样,在Java或C#等经典OO语言中执行此类操作非常痛苦.语言设计完全取决于权衡,这个特殊功能并没有削减C#或Java以及许多其他OO语言.看看为什么……
让我们考虑我的Rectangle =>一分钟的方形示例.也许在我的新语言Z ##中,我选择将对象实例内部存储为由它们继承的对象组成.所以我的Rectangle是内存中的Shape实例,一些属性和方法.然后一个Square只是一个Rectangle形状实例的一些属性和方法.因此,将矩形更改为方形很容易,因为我不需要转换任何东西 – 只需在实例化Square时提供现成的Rectangle.
像C#和Java这样的语言实际上并不这样做 – 它们将对象实例存储为“扁平” – 在C#中,Square实例在内存中不包含Rectangle实例 – 它只是共享Rectangle的接口.因此,在这些语言中实现此功能要慢得多,因为它们实际上必须将整个展平结构复制到新的内存位置.