“压倒一切”子类型中的实例变量:可能的风险?
假设我有一个类 SuperClass 和两个继承自 SuperClass 的子类 SubClassA 和 SubClassB。
abstract class SuperClass{
...
List someList;
...
}
class SubClassA extends SuperClass{
...
List<String> someList;
...
}
class SubClassB extends SuperClass{
...
List<Integer> someList;
...
}
这样很方便,因为我可以在 Superclass
中获取 someList.size()
并在子类中具有类型安全性。 问题是它“感觉”不对,你能想到这个方法有我不知道的潜在危险吗?
Say I had a class SuperClass and two subclasses SubClassA and SubClassB that inherit from SuperClass.
abstract class SuperClass{
...
List someList;
...
}
class SubClassA extends SuperClass{
...
List<String> someList;
...
}
class SubClassB extends SuperClass{
...
List<Integer> someList;
...
}
That way it is convenient because I can get someList.size()
in Superclass
and have Typesafety in the Subclasses.
The problem is that it does not "feel" right, can you think of potential hazards this apporach has that I am not aware of?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一方面,
SuperClass
的任何方法都会看到超类列表,而不是子类的列表。这几乎肯定会导致微妙的错误。例如,当你说你实际得到的是
Superclass
中列表的大小,而不是子类的大小。超类列表可能为空,而子类列表包含元素(反之亦然)。这背后的原因是
SubClassA.someList
不会以任何方式替换或覆盖Superclass.someList
- 它只是隐藏它,因此子类方法会看到SubClassA。 someList
而不是Superclass.someList
。然而,这在Superclass
中绝对没有效果。方法可以设为虚拟(在 Java 中,它们是默认的),但数据成员则不能。For one thing, any method of
SuperClass
sees the superclass list, not that of the subclass. This almost surely leads to subtle bugs. E.g. when you saywhat you actually get is the size of the list in
Superclass
, not that of the subclass. The superclass list may be empty while the subclass list contains elements (or vice versa).The reason behind this is that
SubClassA.someList
does not in any way replace or overrideSuperclass.someList
- it just shadows it, so the subclass methods seeSubClassA.someList
instead ofSuperclass.someList
. However, this has absolutely no effect inSuperclass
. Methods can be made virtual (and in Java, they are by default), but data members can't.这是一个非常糟糕的主意。您真的希望任一子类的实例具有两个列表吗?因为这就是正在发生的事情。您正在声明第二个变量 - 因此超类中的代码将使用一个变量,而子类中的代码将使用另一个变量。在我看来,这只是自找麻烦。
This is a really bad idea. Do you really want an instance of either subclass to have two lists? Because that's what is happening. You're declaring a second variable - so code in the superclass will use one variable, and code in the subclass will use another. That's just asking for trouble, IMO.
我认为你应该定义一个方法而不是类成员变量。这样您就可以在子类中实现方法,而无需担心类型安全。
用我建议的方法替换变量。
谢谢。
I think you should rather define a method instead of the class member variable. So that you will be able to implement methods in your sub classes and don't need to worry about the type safety.
Replace variable with Method i suggest.
thanks.
对我来说似乎违反了 IS-A 和里氏替换原则。如果您有一组 SuperClass 实例,其中每个实例都可以是 SubClassA 或 SubClassB,那么您充其量只会得到一些令人惊讶的行为。
不要这样做。
也许使用泛型会更好:
Seems to break IS-A and the Liskov Substitution Principle to me. If you have a collection of SuperClass instances, each of which can be SubClassA or SubClassB, you'll get some surprising behavior at best.
Don't do it.
Maybe something using generics would be better: