假设我有一个类SuperClass和两个继承自SuperClass的子类SubClassA和SubClassB。
abstract class SuperClass{
...
List someList;
...
}
class SubClassA extends SuperClass{
...
List<String> someList;
...
}
class SubClassB extends SuperClass{
...
List<Integer> someList;
...
}
这样很方便,因为我可以在someList.size()
中获得Superclass
并在子类中拥有类型安全。
问题是它没有“感觉”正确,你能想到这个我不知道的潜在危险吗?
答案 0 :(得分:8)
首先,SuperClass
的任何方法都会看到超类列表,而不是子类的列表。这几乎肯定会导致微妙的错误。例如。当你说
我可以在
中获得someList.size()
Superclass
实际得到的是Superclass
中列表的大小,而不是子类的大小。超类列表可以为空,而子类列表包含元素(反之亦然)。
这背后的原因是SubClassA.someList
不会以任何方式替换或覆盖Superclass.someList
- 它只会遮蔽它,因此子类方法会看到SubClassA.someList
而不是Superclass.someList
。但是,这对Superclass
完全没有影响。方法可以是虚拟的(在Java中,它们是默认的),但数据成员不能。
答案 1 :(得分:1)
这是一个非常糟糕的主意。你真的想要一个子类的实例拥有两个列表吗?因为那就是发生了什么。你要声明第二个变量 - 所以超类中的代码将使用一个变量,子类中的代码将使用另一个变量。这只是在寻找麻烦,IMO。
答案 2 :(得分:1)
似乎打破IS-A和Liskov替代原则给我。如果你有一个SuperClass实例的集合,每个实例都可以是SubClassA或SubClassB,那么你最多会得到一些令人惊讶的行为。
不要这样做。
使用泛型的东西可能更好:
public class X<T>
{
private List<T> list;
}
答案 3 :(得分:1)
我认为您应该定义一个方法而不是类成员变量。这样您就可以在子类中实现方法,而不必担心类型安全性。
用方法i建议替换变量。
感谢。