Это то, что 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));