我的理解是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& ClassB属于超类,但我想知道为什么会失败。
答案 0 :(得分:5)
因为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
和{ {1}}类来实现它。例如:
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
提供的实现。
答案 1 :(得分:1)
实际上,在一些较宽松的类型语言中,您的方法可行。在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");
}
}
}
答案 2 :(得分:0)
您的方法失败,因为类Object
没有名为exampleMethod()
的方法。
如果你给出例如,会发生什么? Number
方法?
答案 3 :(得分:0)
除非你没有将你的对象投射到A / B.引用将保持为Object类, Object类不包含任何名为exampleMethod(String str)的方法。因此,您需要将其强制转换为已实现exampleMethod的类。你可以做这样的事情:
public void execute(Object o) {
if (o instanceof A) {
((A)o).exampleMethod("test");
}
if (o instanceof B) {
((B)o).exampleMethod("test");
}
}