我有一个名为“I”的界面:
package org.example;
public interface I {
}
非常简单: - )
我有实现此接口的类。它们被称为A,B,C,D,E等。
A类和B类具有特定方法,如下所示。其他课程没有。
public class A implements I {
public void sayHelloFromA() {
System.out.println("Hello from A");
}
}
public class B implements I {
public void sayHelloFromB() {
System.out.println("Hello from B");
}
}
我的main方法遍历I对象列表,我想根据类的类型执行特定的操作。
package org.example;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(final String[] args) {
final A a = new A();
final B b = new B();
final C c = new C();
final List<I> list = new ArrayList<I>();
list.add(a);
list.add(b);
list.add(c);
for (final I i : list) {
sayHello(i);
}
}
public static void sayHello(final A a) {
a.sayHelloFromA();
}
public static void sayHello(final B b) {
b.sayHelloFromB();
}
public static void sayHello(final I i) {
System.out.println("Unsupported");
}
}
这是问题所在;输出是:
Unsupported
Unsupported
Unsupported
我知道它不起作用,但问题是,如何在不使用instanceof或reflexion的情况下完成这项工作。诀窍是我无法修改界面我(在现实生活中,我认为它是一个javax.swing.tree.TreeNode)。
我不使用访问者模式,因为我相信当你有一组固定的类类型并且你在这些类型上添加新操作时访问者模式更适合。在我的现实生活中,恰恰相反:我只有一个操作,而且我经常在列表中添加新类型......
答案 0 :(得分:3)
由于Java是一种静态类型语言,因此决定在编译时完成调用哪个方法重载,这意味着您不能根据实例的实际类型调用重载方法,只能通过其声明类型。
如果您不想使用反射来查找您的实例所在的类,但您可以更改A和B,则可以添加另一个接口以供它们实现:
public interface I2 {
void sayHello();
}
让A
和B
实现它:
public class A implements I, I2 {
public void sayHelloFromA() {
System.out.println("Hello from A");
}
public void sayHello() {
sayHelloFromA();
}
}
public class B implements I, I2 {
public void sayHelloFromB() {
System.out.println("Hello from B");
}
public void sayHello() {
sayHelloFromB();
}
}