TL; дрРекурсивного Generic и свободный интерфейс
Попытка реализовать иерархический свободно интерфейс таким образом, что я могу объединить узлов дочерних классов, а также класс автономным, но получить параметр типа не входит в его связанных ошибках ,
Подробности
Я пытаюсь добиться решения, так что я могу создать что-то такое, что я могу сделать что-то вроде:
farm
.animal()
.cat()
.meow()
.findsHuman()
.saysHello()
.done()
.done()
.dog()
.bark()
.chacesCar()
.findsHuman()
.saysHello()
.done()
.done()
.done()
.human()
.saysHello()
.done();
, а также быть в состоянии сделать:
Human human = new Human()
.saysHello()
Я пришел близко, используя различные стратегии, но не смог получить описанную гибкость.
Моя текущая попытка использует следующие классы:
abstract class Base<T extends Base<T>>{
private T parent;
Base(){
}
Base(T parent){
this.parent = parent;
}
public T done() throws NullPointerException{
if (parent != null){
return (T) parent;
}
throw new NullPointerException();
}
}
class Farm<T extends Base<T>> extends Base{
private Animal<Farm<T>> animal;
private Human<Farm<T>> human;
public Farm(){
super();
this.animal = new Animal(this);
this.human = new Human(this);
}
public Animal<Farm> animal(){
return this.animal;
}
public Human<Farm<T>> human(){
return this.human;
}
}
class Animal <T extends Base<T>> extends Base{
private Cat<Animal<T>> cat;
private Dog<Animal<T>> dog;
public Animal(){
super();
init();
}
public Animal(T parent){
super(parent);
init();
}
private void init(){
this.cat = new Cat(this);
this.dog = new Dog(this);
}
public Cat<Animal<T>> cat(){
return cat;
}
public Dog<Animal<T>> dog(){
return dog;
}
}
class Human<T extends Base<T>> extends Base{
public Human<T> saysHello(){
System.out.println("human says hi");
return this;
}
}
class Cat <T extends Base<T>> extends Base{
private Human<Cat> human;
public Cat(){
super();
init();
}
public Cat(T parent){
super(parent);
init();
}
private void init(){
this.human = new Human();
}
public Cat<T> meow(){
System.out.println("cat says meow");
return this;
}
public Human<Cat<T>> findsHuman(){
return this.human;
}
}
class Dog <T extends Base<T>> extends Base{
private Human<Dog> human;
public Dog(){
super();
init();
}
public Dog(T parent){
super(parent);
init();
}
private void init(){
this.human = new Human();
}
public Dog<T> bark(){
System.out.println("dog says woof");
return this;
}
public Dog<T> chacesCar(){
System.out.println("cat drinks milk");
return this;
}
public Human<Dog<T>> findsHuman(){
return this.human;
}
}
Ошибки я вижу обычно:
Animal.java:4: параметр животных типа не входят в его связанном частном Cat Кот; Animal.java:5: параметр типа Animal не находится в пределах своей связанной собаки Dog Dog;
Применяют для всех подобных ссылок, а также относящиеся к моему примеру желаемому случай:
не может найти символ символ: метод собаки() местоположение: класс Base.dog()
Я пробовал использовать следующие решения, которые, казалось, решали аналогичные проблемы, но безуспешно, поэтому всякая поддержка приветствуется.
Ссылки
Is there a way to refer to the current type with a type variable?
http://vyazelenko.com/2012/03/02/recursive-generics-to-the-rescue/
ИМХО вы используете _java_ дженерики для того, что они не предназначены. Это будет отлично работать на C++, но java generics - не то же самое. _Generics вредны, и это один из примеров. Разумеется, существуют и другие * решения для разработки программного обеспечения * для ваших нужд, а не в * программном искусстве *, которое вы вставляете. Когда все так сложно, как показано здесь, возможно, что-то не так. –
Думаю, я нашел решение. Я обновил свой ответ соответственно. – morpheus05
@AlfonsoNishikawa Я согласен с тем, что это может подтолкнуть пределы этого шаблона и было за пределами моего первоначального понимания, поэтому я подумал, что попрошу сообщества подумать. – SS44