在方法参数中使用对象超类



我的理解是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方法,从而给您错误。您至少应该对ClassAClassB类进行向下转换以执行代码:

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

但是,在进行向下转换之前,必须确保o参数是ClassAClassB实例,否则可能会遇到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");
    }
}

仍然,这是相当笨拙的。由于ClassAClassB类共享具有相同签名(相同名称,相同参数,相同返回类型)的方法,您可以使用具有此方法的接口并使ClassAClassB类实现它。例如:

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

通过这种方式,你可以将ClassAClassB的实例传递给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");
    }
}

最新更新