钻石问题真的可以解决吗? [英] Can the Diamond Problem be really solved?

查看:92
本文介绍了钻石问题真的可以解决吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

OO编程中的一个典型问题是菱形问题.我有一个带有两个子类B和C的父类A.A有一个抽象方法,B和C实现了它.现在,我有一个子类D,它继承了B C.菱形问题是,D应该使用哪种实现方式,B之一还是C之一?

A typical problem in OO programming is the diamond problem. I have parent class A with two sub-classes B and C. A has an abstract method, B and C implement it. Now I have a sub-class D, that inherits of B and C. The diamond problem is now, what implementation shall D use, the one of B or the one of C?

人们声称Java没有钻石问题.我只能对接口进行多重继承,并且由于它们没有实现,所以我没有任何钻石问题.这是真的吗?我不这么认为. 请参见下文:

People claim Java knows no diamond problem. I can only have multiple inheritance with interfaces and since they have no implementation, I have no diamond problem. Is this really true? I don't think so. See below:

[拆卸的车辆示例]

[removed vehicle example]

钻石问题是否总是导致类设计不良的原因,并且程序员和编译器都不需要解决这些问题,因为它首先不应该存在?

Is a diamond problem always the cause of bad class design and something neither programmer nor compiler needs to solve, because it shouldn't exist in the first place?

更新:也许我的示例选择不当.

Update: Maybe my example was poorly chosen.

查看此图片


(来源: suffolk.edu )


(source: suffolk.edu)

当然,您可以在C ++中使Person虚拟,因此内存中将只有一个person实例,但是真正的问题仍然存在.您将如何为GradTeachingFellow实现getDepartment()?考虑一下,他可能是一个部门的学生,而在另一个部门任教.因此,您可以归还一个部门,也可以归还另一个部门.没有完美的解决方案,而且没有实现可以继承的事实(例如Student和Teacher都可以是接口)似乎并不能解决我的问题.

Of course you can make Person virtual in C++ and thus you will only have one instance of person in memory, but the real problem persists IMHO. How would you implement getDepartment() for GradTeachingFellow? Consider, he might be student in one department and teach in another one. So you can either return one department or the other one; there is no perfect solution to the problem and the fact that no implementation might be inherited (e.g. Student and Teacher could both be interfaces) doesn't seem to solve the problem to me.

推荐答案

您看到的是如何违反

What you're seeing is how violations of the Liskov Substitution Principle make it really hard to have a working, logical object-oriented structure.
Basically, (public) inheritance should only narrow the purpose of the class, not extend it. In this case, by inheriting from two types of vehicles you are in fact extending the purpose, and as you noticed, it doesn't work - move should be very different for a water vehicle than for a road vehicle.
You could instead aggregate a water vehicle and a ground vehicle object in your amphibious vehicle and decide externally which of the two will be appropriate to the current situation.
Alternatively you could decide that the "vehicle" class is needlessly generic and you'll have separate interfaces for both. That doesn't solve the problem for your amphibious vehicle on its own though - if you call the movement method "move" in both interfaces, you'll still have trouble. So I'd suggest aggregation instead of inheritance.

这篇关于钻石问题真的可以解决吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆