我有超类A,它由子类B1和B2扩展。然后,我有五个子类(C1,C2,C3,C4,C5),可以扩展B1或B2。
我正在尝试创建一个包含这五个子类中的每一个的数组。
这些对象都被实例化为类型A的实例。
ClassA[] objects = new ClassA[5];
我尝试将每个对象重新分配给其中一个子类:
objects[0] = new ClassC1;
objects[1] = new ClassC2; // etc...
此时,A类中存在的任何方法都可以正常工作,但是找不到B1 / B2或其他子类中定义的方法:
objects[0].MethodFromC1(); // returns a "symbol not found" error
instanceof关键字表示objects [0]是A,B1 / B2和C1类的实例。
我可以做些什么来维护我的类对象数组(循环并执行操作),同时让我的代码识别子类的方法?
答案 0 :(得分:3)
如果你正在做很多基于类的instanceof
和条件逻辑,那么你完全错过了面向对象语言的好处。坚持C。
例如,您应该有一些方法do()
,它在ClassA
中是抽象的,但在ClassB
和ClassC
中实现。然后迭代数组并在那里的每个对象上调用do()
。多态调用将导致调用正确的do()
。
希望有所帮助。
答案 1 :(得分:1)
您可以在if语句中使用instanceof关键字,并将对象强制转换为所需类型。例如,
for (ClassA obj : objects) {
// do something common...
if (obj instanceof ClassC1) {
ClassC1 c1Obj = (ClassC1) obj;
c1Obj.MethodFromC1();
}
}
答案 2 :(得分:1)
objects
数组中的元素对ClassC1
一无所知,因为它们只保证是ClassA
的成员。
例如,如果您的类层次结构为Animal
和子类Cat
及其子类Lion
,则您尝试调用Animal.maimSafarigoer()
方法。 Animal
一般对safarigoers一无所知,只有Lion
知道如何做到这一点。
使用instanceof
运算符检查您是否在特定子类型上运行。
(抱歉可怕的比喻。:-))
答案 3 :(得分:1)
您正尝试在Java中实现变体。这个主题长期以来一直是我最讨厌这种语言的事情之一。
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
我列出了大约8种不太理想的方法来做变种。