2013-02-11 2 views
3

Рассмотрим следующий код:Ошибка компиляции с родовыми типами циклических общих зависимостей

public abstract class Animal<A extends Cage<? extends Animal<A>>> 
{ 
    private A cage; 

    public A getCage() 
    { 
     return this.cage; 
    } 

    public void setCage(final A cage) 
    { 
     this.cage = cage; 
    } 
} 

public abstract class Cage<A extends Animal<? extends Cage<A>>> 
{ 
    private List<A> animals; 

    public void addAnimal(final A animal) 
    { 
     if (animal != null) 
     { 
      animal.setCage(this); 

      if (this.animals == null) 
      { 
       this.animals = new ArrayList<A>(); 
      } 

      this.animals.add(animal); 
     } 
    } 
} 

Эти классы продлено другими классами.

Этот код не компилировать на линии

animal.setCage(this); 

Любые мысли о том, почему этот код не компилируется и как это может быть фиксированной? Мы используем Java 1.6.

+0

Не могли бы вы попробовать с: ** 1 °) ** 'класс животных < A удлиняет клетку , C extends Animal > '; ** 2 °) ** 'class Cage , C extends Cage >'; ** 3 °) ** 'animal.setCage ((C) this);'? – sp00m

+0

Спасибо @ sp00m, это работает! Блестящий материал. Если вы добавите это как ответ, я приму его, чтобы вы получили кредит за предложение этого. – manish

+0

Добро пожаловать, я сделал * реальный * ответ. – sp00m

ответ

-1

Это должно удовлетворить ваши потребности:

public abstract class Animal<A extends Cage<C, A>, C extends Animal<A, C>> { 

    private A cage; 

    public A getCage() { 
     return this.cage; 
    } 

    public void setCage(final A cage) { 
     this.cage = cage; 
    } 

} 

public abstract class Cage<A extends Animal<C, A>, C extends Cage<A, C>> { 

    private List<A> animals; 

    @SuppressWarnings("unchecked") 
    public void addAnimal(final A animal) { 
     if (animal != null) { 
      animal.setCage((C) this); 
      if (this.animals == null) { 
       this.animals = new ArrayList<A>(); 
      } 
      this.animals.add(animal); 
     } 
    } 

} 
+1

'(C) это не безопасно. – newacct

+0

@newacct Я думаю, что «это» - это все, что поддается C', я ошибаюсь? Или в каком случае 'this' может быть другого типа, чем' C'? – sp00m

+1

, например, 'class Dog extends Animal ', 'class DogCage расширяет Cage ' и 'class AnotherDogCage расширяет Cage ' – newacct

0

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

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

0

Для методов, которые вы показали, это, кажется, достаточно:

public abstract class Animal<C> { 

    private C cage; 

    public C getCage() { 
     return this.cage; 
    } 

    public void setCage(final C cage) { 
     this.cage = cage; 
    } 

} 

public abstract class Cage<A extends Animal<C>, C> { 

    private List<A> animals; 

    public abstract C getThis(); 

    public void addAnimal(final A animal) { 
     if (animal != null) { 
      animal.setCage(getThis()); 
      if (this.animals == null) { 
       this.animals = new ArrayList<A>(); 
      } 
      this.animals.add(animal); 
     } 
    } 

} 

public class CatCage extends Cage<Cat, CatCage> { 
    @Override 
    public CatCage getThis() { return this; } 
} 
Смежные вопросы