Я знаю, что есть много вопросов по этой теме, но, к сожалению, они не могут помочь мне устранить мои неясности. Прежде всего, посмотрите на следующий пример. Я не понимаю, почему следующий "add" -method someCage.add(rat1) не работает и прерывается со следующим исключением:
Исключение в потоке "main" java.lang.Error: неразрешенная компиляция проблема: метод add (capture # 2-of? extends Animal) в типе Клетка не применяется для аргументы (Rat)
Это та же причина, почему Cage<Rat> не является Cage<Animal>? Если да, я не понимаю этого в этом примере, поэтому я не уверен, что именно делает компилятор. Вот пример кода:
package exe;
import cage.Cage;
import animals.Animal;
import animals.Ape;
import animals.Lion;
import animals.Rat;
public class Main {
    public static void main(String[] args) {
        Lion lion1 = new Lion(true, 4, "Lion King", 8);
        Lion lion2 = new Lion(true, 4, "King of Animals", 9);
        Ape ape1 = new Ape(true, 2, "Gimpanse", true);
        Ape ape2 = new Ape(true, 2, "Orang Utan", true);
        Rat rat1 = new Rat(true, 4, "RatBoy", true);
        Rat rat2 = new Rat(true, 4, "RatGirl", true);
        Rat rat3 = new Rat(true, 4, "RatChild", true);
        Cage<Animal> animalCage = new Cage<Animal>();
        animalCage.add(rat2);
        animalCage.add(lion2);
        Cage<Rat> ratCage = new Cage<Rat>();
        ratCage.add(rat3);
        ratCage.add(rat1);
        ratCage.add(rat2);
//      ratCage.add(lion1); //Not Possible. A Lion is no rat
        Cage<Lion> lionCage = new Cage<Lion>();
        lionCage.add(lion2);
        lionCage.add(lion1);
        Cage<? extends Animal> someCage = new Cage<Animal>(); //? = "unknown type that is a subtype of Animal, possibly Animal itself"
        someCage = ratCage; //OK
//      someCage = animalCage; //OK
        someCage.add(rat1);  //Not Possible, but why?
        animalCage.showAnimals();
        System.out.println("\nRatCage........");
        ratCage.showAnimals();
        System.out.println("\nLionCage........");
        lionCage.showAnimals();
        System.out.println("\nSomeCage........");
        someCage.showAnimals();
    }
}
Это класс клетки:
package cage;
import java.util.HashSet;
import java.util.Set;
import animals.Animal;
    public class Cage<T extends Animal> {  //A cage for some types of animals
        private Set<T> cage = new HashSet<T>();
        public void add(T animal)  {
            cage.add(animal);
        }
        public void showAnimals()  {
            for (T animal : cage) {
                System.out.println(animal.getName());
            }
        }
    }
Кроме того, я был бы доволен, если бы вы могли дать мне осмысленный "супер" пример с этим кодом-клеткой. До сих пор я не понимал, как его использовать. Есть много теоретических примеров, и я читал о концепции PECS, но так или иначе я не смог использовать ее в осмысленном вопросе. Что означало бы иметь "потребитель" (с супер) в этом примере?
