Подтвердить что ты не робот

Способ сделать метод родительского класса Java возвращать объект дочернего класса

Есть ли элегантный способ заставить Java-метод размещаться в родительском классе возвращать объект дочернего класса, когда этот метод вызывается из дочернего класса?

Я хочу реализовать это, не используя дополнительные интерфейсы и дополнительные методы, и использовать это без применения классов, вспомогательных аргументов и т.д.

Update:

Извините, что я не был таким ясным.

Я хочу реализовать цепочку методов, но у меня проблемы с методами родительского класса: я теряю доступ к методам дочерних классов, когда я вызываю методы родительского класса... Я полагаю, что я представил суть моей идеи.

Поэтому методы должны возвращать объект this класса this.getClass().

4b9b3361

Ответ 1

Если вы просто ищете цепочку методов для определенного подкласса, тогда должно работать следующее:

public class Parent<T> {

  public T example() {
    System.out.println(this.getClass().getCanonicalName());
    return (T)this;
  }
}

который может быть абстрактным, если хотите, затем некоторые дочерние объекты, которые задают общий тип возвращаемого значения (это означает, что вы не можете получить доступ к childBMethod из ChildA):

public class ChildA extends Parent<ChildA> {

  public ChildA childAMethod() {
    System.out.println(this.getClass().getCanonicalName());
    return this;
  }
}

public class ChildB extends Parent<ChildB> {

  public ChildB childBMethod() {
    return this;
  }
}

а затем вы его используете как

public class Main {

  public static void main(String[] args) {
    ChildA childA = new ChildA();
    ChildB childB = new ChildB();

    childA.example().childAMethod().example();
    childB.example().childBMethod().example();
  }
}

вывод будет

org.example.inheritance.ChildA 
org.example.inheritance.ChildA 
org.example.inheritance.ChildA 
org.example.inheritance.ChildB 
org.example.inheritance.ChildB

Ответ 2

Чего вы пытаетесь достичь? Это звучит неплохо. Родительский класс не должен знать ничего о своих дочерних элементах. Кажется, это ужасно близко к нарушению Принципа замены Лискова. Я чувствую, что ваш вариант использования будет лучше служить, изменив общий дизайн, но трудно сказать без дополнительной информации.

Извините, что звучит немного педантично, но я немного боюсь, когда читаю такой вопрос.

Ответ 3

Просто продемонстрировать:

public Animal myMethod(){
  if(this isinstanceof Animal){
     return new Animal();
  }
  else{

     return this.getClass().newInstance();
  }
}

Ответ 4

Вы можете вызвать this.getClass(), чтобы получить класс выполнения.

Однако это не обязательно класс, называемый методом (он может быть еще ниже по иерархии).

И вам нужно будет использовать отражение для создания новых экземпляров, что сложно, потому что вы не знаете, какие конструкторы имеют дочерний класс.

return this.getClass().newInstance(); // sometimes works

Ответ 5

Я точно знаю, что вы имеете в виду. В Perl есть переменная $class, которая означает, что вы вызываете некоторый метод factory в подклассе, даже если он не переопределяется в подклассе, если он инициирует любые экземпляры $class будет создан экземпляр подкласса.

Smalltalk, Objective-C, многие другие языки имеют аналогичную возможность.

Увы, в Java нет такого эквивалентного объекта.

Ответ 6

public class Parent {
    public Parent myMethod(){
        return this;
    }
}
public class Child extends Parent {}

И вызывать его как

       Parent c = (new Child()).myMethod();
       System.out.println(c.getClass());

Правильно ли это решение? Если это так, то как это отличается от решения №1?