Java中是否有一种方法可以根据对象的子类来调用不同的子方法?

时间:2019-10-08 15:43:58

标签: java overriding

在我的项目中,我有一个超类和两个从其扩展的子类。在超类中有一个方法,在每个子类中都有不同的方法被覆盖。 我想知道是否有可能引入一种方法(在另一个类中),该方法将任一子类的对象作为参数并调用子类之一中重写的方法(取决于对象所属的子类)。

public class Superclass{
    public int method(){return 0;}
}
public class Subclass1 extends Superclass{
    public int method(){return 1;}
}
public class Subclass2 extends Superclass{
    public int method(){return 2;}
}
public class CallingClass{
    public static int dependantCall(Superclass parameter){return parameter.method}

我希望能够做类似

的操作
Subclass1 subclassObject = new Subclass1;
System.out.println(CallingClass.dependantCall(subclassObject));

并获取输出

1

3 个答案:

答案 0 :(得分:3)

这就是多态性的目的!将超类定义为参数类型将使您可以传入任何一个子类。

例如,在您的其他课程中,您可以这样定义它:

// classes Dog and Cat extend Animal and override makeNoise()
class Owner{

  playWith(Animal a){
    a.makeNoise();
  }

}

现在,所有者可以接受owner.makeNoise(cat)和owner.makeNoise(dog)

更多阅读内容:https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html

答案 1 :(得分:1)

是的,这完全有可能。该方法如下所示:

public <T extends Superclass> void foo(T subclassObject) {
...
} 

或者:

public void foo(Superclass obj) {
...
}

请注意,在上述方法中,您也可以传递子类的对象(它们是协变数据类型)。

答案 2 :(得分:0)

这是Java在创建子目录时默认执行的操作,因此无需执行任何特殊操作。每个对象在运行时都会携带其类型信息,并且所调用的方法始终是该对象最具体的方法。示例:

public class Doer {
  public void doSomething() {
    // Body presence
  };
}

public class Painter extends Doer {
  @Override
  public void doSomething() {
    // Paint here
  }
}

public class Manager extends Doer {
  @Override
  public void doSomething() {
    // Micromanage here
  }
}

// Elsewhere in your code: 
public void busyness(Doer doer) {
   doer.doSomething();
}

一种样式注解:如果可能的话,应该更喜欢使用接口而不是基类(仅当您要在子类之间共享实现时才应使用基类)。接口示例:

public interface Doer {
  void doSomething();
}

public class JackOfAllTrades implements Does {
  @Override
  public void doSomething() {
     // Do whatever necessary
  }
}

// Client code stays exactly the same as above: 
public void busyness(Doer doer) {
   doer.doSomething();
}

请注意,在Java中,一个类只能具有一个基类,但可以实现多个接口。

@Override注释不是严格要求的,但是它们可以帮助Java编译器为您发现一些错误(例如,如果您错误打印方法名称)。

在您的示例中,它看起来像

public class CallingClass {
  public static int dependantCall(Superclass parameter) {
    return parameter.method();
  }
}

Subclass1 subclassObject = new Subclass1();
System.out.println(CallingClass.dependantCall(subclassObject));