我的理解是Java中的每个类都是Object超类的子类。因此,为什么是我的编译器给我以下代码的错误:
public class ClassA {
public ClassA(){}
public String exampleMethod(String str){
//manipulate string
return str;
}
}
public class ClassB {
public ClassB(){}
public String exampleMethod(String str){
//manipulate string
return str;
}
}
public class Manager {
public Manager(){
execute(new ClassA());
execute(new ClassB());
}
public void execute(Object o){
o.exampleMethod("test");
}
}
如果ClassA是Object的子对象,为什么我不能从'o'变量调用方法?我知道我可以把ClassA &
因为Object
类没有定义exampleMethod
方法,从而给您错误。您至少应该对ClassA
或ClassB
类进行向下转换以执行代码:
public void execute(Object o) {
//this makes the code compiles
((ClassA)o).exampleMethod("test");
}
但是,在进行向下转换之前,必须确保o
参数是ClassA
或ClassB
实例,否则可能会遇到ClassCastException
异常。您可以通过使用instanceof
:
public void execute(Object o) {
//this makes the code compiles
//and assures that you won't have a ClassCastException
if (o instanceof ClassA) {
((A)o).exampleMethod("test");
}
if (o instanceof ClassB) {
((B)o).exampleMethod("test");
}
}
仍然,这是相当笨拙的。由于ClassA
和ClassB
类共享具有相同签名(相同名称,相同参数,相同返回类型)的方法,您可以使用具有此方法的接口并使ClassA
和ClassB
类实现它。例如:
interface IExample {
String exampleMethod(String str);
}
public class ClassA implements IExample {
//current implementation...
}
public class ClassB implements IExample {
//current implementation...
}
然后可以将Manager
类中的代码缩短为:
public void execute(Object o) {
if (o instanceof IExample) {
((IExample)o).exampleMethod("test");
}
}
或者更好:
public void execute(IExample o) {
o.exampleMethod("test");
}
通过这种方式,你可以将ClassA
或ClassB
的实例传递给execute
方法,它的行为将取决于每个类给exampleMethod
的实现。
实际上,在一些松散类型的语言中,您的方法是可行的。在Java中,您需要将execute()
方法修改为如下内容:
public class Manager {
...
public void execute(Object o){
if (o instanceof ClassA) {
((ClassA) o).exampleMethod("test");
} else if (o instanceof ClassB) {
((ClassB) o).exampleMethod("test");
}
}
}
您的方法失败了,因为类Object
没有称为exampleMethod()
的方法。
如果你给例如Number
的方法会发生什么?
除非你不将对象强制转换为A/B。对象类不包含任何名为exampleemethod (String str)的方法。因此,您需要将其强制转换为实现了exampleemethod的类。你可以这样做:
public void execute(Object o) {
if (o instanceof A) {
((A)o).exampleMethod("test");
}
if (o instanceof B) {
((B)o).exampleMethod("test");
}
}