Есть ли способ в Java для вызова другого дочернего метода в зависимости от того, какой подкласс является объектом? - PullRequest
1 голос
/ 08 октября 2019

В моем проекте у меня есть суперкласс и два подкласса, выходящие из него. В суперклассе есть метод, который по-разному переопределяется в каждом подклассе. Я хочу знать, возможно ли ввести метод (в другом классе), который принимает объект любого подкласса в качестве параметра и вызывает метод, переопределенный в одном из подклассов (в зависимости от того, к какому подклассу принадлежит объект).

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 ]

3 голосов
/ 08 октября 2019

Вот для чего нужен полиморфизм! Определение суперкласса в качестве типа параметра позволит вам передать любой подкласс в.

Например, в другом классе вы можете определить его следующим образом:

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

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

}

Теперь владелец может принять владельца.makeNoise (кошка) и owner.makeNoise (собака)

More reading: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html

1 голос
/ 08 октября 2019

Да, это вполне возможно. Вот как будет выглядеть этот метод:

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

Или:

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

Обратите внимание, что в вышеприведенном методе вы также можете передавать объекты подклассов (они являются ковариантными типами данных).

0 голосов
/ 08 октября 2019

Это то, что 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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...