Способ сделать метод родительского класса Java возвращать объект дочернего класса
Есть ли элегантный способ заставить Java-метод размещаться в родительском классе возвращать объект дочернего класса, когда этот метод вызывается из дочернего класса?
Я хочу реализовать это, не используя дополнительные интерфейсы и дополнительные методы, и использовать это без применения классов, вспомогательных аргументов и т.д.
Update:
Извините, что я не был таким ясным.
Я хочу реализовать цепочку методов, но у меня проблемы с методами родительского класса: я теряю доступ к методам дочерних классов, когда я вызываю методы родительского класса... Я полагаю, что я представил суть моей идеи.
Поэтому методы должны возвращать объект this
класса this.getClass()
.
Ответы
Ответ 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?