0

My understanding is that every class in Java is a child of the Object superclass. Why, therefore, is it my compiler giving me errors for the following code:

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");
   }
}

If ClassA is a child of Object, why can I not call methods from the 'o' variable? I'm aware that I could just put ClassA & ClassB under a superclass, but I want to know why this fails.

4

4 回答 4

5

因为Object类没有定义exampleMethod方法,从而给你错误。你至少应该做一个向下转换的 oClassAClassB类来执行你的代码:

public void execute(Object o) {
    //this makes the code compiles
    ((ClassA)o).exampleMethod("test");
}

尽管如此,在进行向下转换之前,您必须确保o参数是一个ClassA或实例,否则您可能会遇到异常。您可以使用以下方法实现此目的:ClassBClassCastExceptioninstanceof

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");
    }
}

不过,这还是很笨拙。由于ClassAClassB类共享一个具有相同签名(相同名称、相同参数、相同返回类型)的方法,因此您可以使用具有此方法的接口以及 makeClassAClassB类来实现它。例如:

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.

于 2013-06-17T06:29:29.827 回答
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");
            }
    }
}
于 2013-06-17T06:35:59.227 回答
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");
    }
}
于 2013-06-17T06:33:10.593 回答
0

您的方法失败了,因为该类Object没有一个名为exampleMethod().

如果你给例如Number方法会发生什么?

于 2013-06-17T06:30:08.093 回答