在泛型中扩展的超级和隐藏的有用示例? [英] Useful example with super and obscurity with extends in Generics?

查看:120
本文介绍了在泛型中扩展的超级和隐藏的有用示例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道关于这个话题有很多问题,但不幸的是,他们无法帮助我消除我的隐晦。首先,看下面的例子。我不明白,为什么下面的添加 - 方法 someCage.add(rat1)不起作用,并且以下例外情况中止:


线程main中的异常java.lang.Error:未解析的编译
问题:方法add(capture#2-of?extends Animal)in
Cage类型不适用于
参数(Rat)

这是为什么 Cage< Rat> 不是 Cage< Animal> ?如果是的话,我不明白这个例子,所以我不确定编译器究竟做了什么。代码示例如下:

  package exe; 

导入cage.Cage;
进口动物。动物;
进口动物.Ape;
进口动物。狮子;
进口animals.Rat;

public class Main {

public static void main(String [] args){
Lion lion1 = new Lion(true,4,Lion King, 8);
狮子狮子2 =新狮子(true,4,动物之王,9);
Ape ape1 =新猿(true,2,Gimpanse,true);
Ape ape2 =新猿(true,2,Orang Utan,true);
大鼠rat1 =新大鼠(true,4,RatBoy,true);
大鼠rat2 =新大鼠(true,4,RatGirl,true);
大鼠rat3 =新大鼠(true,4,RatChild,true);

笼子<动物> animalCage = new Cage< Animal>();
animalCage.add(rat2);
animalCage.add(lion2);

笼子< Rat> ratCage = new Cage< Rat>();
ratCage.add(rat3);
ratCage.add(rat1);
ratCage.add(rat2);
// ratCage.add(lion1); //不可能。狮子不是老鼠

笼子<狮子> lionCage = new Cage< Lion>();
lionCage.add(lion2);
lionCage.add(lion1);

笼子<?延伸动物> someCage = new Cage< Animal>(); //? =未知类型是动物的一个子类型,可能是动物本身
someCage = ratCage; // OK
// someCage = animalCage; // OK
someCage.add(rat1); //不可能,但是为什么?

animalCage.showAnimals();
System.out.println(\\\
RatCage ........);
ratCage.showAnimals();
System.out.println(\\\
LionCage ........);
lionCage.showAnimals();
System.out.println(\\\
SomeCage ........);
someCage.showAnimals();


这是笼子类:

 包装箱; 

import java.util.HashSet;
import java.util.Set;

进口动物。动物;

公开课笼子< T延伸动物> {//一些动物类型的笼子
private Set< T> cage = new HashSet< T>();

public void add(T animal){
cage.add(animal);

$ b $ public void showAnimals(){
for(T animal:cage){
System.out.println(animal.getName());
}
}
}

此外,我会很高兴如果你能给我一个有意义的超级的例子,这个动物笼代码。直到现在我还没有理解如何使用它。有很多理论的例子,我读了PECS的概念,但无论如何,我还没有把它用在一个有意义的事情上。在这个例子中,有一个消费者(与超级)是什么意思? 超级界限 >

引入的 transferTo()方法接受 Cage <? super T> - 一个拥有 T 超类的笼子。由于T是其超类的一个实例,因此可以将 T 放入 Cage中。

  public static class Cage< T extends Animal> {
私人套餐< T> pen = new HashSet< T>();

public void add(T animal){
pen.add(animal);
}

/ *将子类放入超类笼子* /
public void transferTo(Cage< .pen.addAll(this.pen);
}

public void showAnimals(){
System.out.println(pen);


$ / code $ / pre

现在我们来看看< ?

  public static class Animal {
public String toString( ){
return getClass()。getSimpleName();


public static class Rat extends Animal {}
public static class Lion extends Animal {}
public static class Cage< T extends Animal> {/ * above * /}

public static void main(String [] args){
Cage< Animal>动物=新Cage< Animal>();
笼< Lion> lions = new Cage< Lion>();
animals.add(new Rat()); //确定将鼠放入笼中<动物>
lions.add(new Lion());
lions.transferTo(动物); //调用超类方法
animals.showAnimals();
}

输出:

  [Rat,Lion] 




另一个重要的概念是,尽管这是真的:

  Lion instanceof Animal // true 

不是 真的

 笼<狮GT; instanceof Cage< Animal> // false 

它不是这种情况,这段代码可以编译:

 笼子<动物>动物; 
笼< Lion>狮子。
动物=狮子; //这个任务是不允许的
animals.add(rat); //如果执行此操作,我们会在笼子<狮子>


I know that there are a lot of questions about this topic, but unfortunately they couldn't help me to eliminate my obscurities. First of all, look at the following example. I don't understand, why the following "add"-method someCage.add(rat1) doesn't work and aborts with the following exception:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method add(capture#2-of ? extends Animal) in the type Cage is not applicable for the arguments (Rat)

Is this the same reason why Cage<Rat> is not a Cage<Animal>? If yes, I don't understand it in this example, so I'm not sure what the compiler exactly does. Here is the code example:

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();
    }
}

This is the cage class:

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());
            }
        }
    }

Moreover, I would be pleased if you could give me a meaningful "super" example with this animal-cage-code. Until now I haven't understood how to use it. There are a lot of theoretical examples and I read about the PECS concept but anyhow I wasn't able to employ it in a meaningful matter yet. What would it mean to have a "consumer" (with super) in this example?

解决方案

Example of super bound

The introduced transferTo() method accepts Cage<? super T> - a Cage that holds a superclass of T. Because T is an instanceof its superclass, it's OK to put a T in a Cage<? super T>.

public static class Cage<T extends Animal> { 
    private Set<T> pen = new HashSet<T>();

    public void add(T animal) {
        pen.add(animal);
    }

    /* It's OK to put subclasses into a cage of super class */
    public void transferTo(Cage<? super T> cage) {
        cage.pen.addAll(this.pen);
    }

    public void showAnimals() {
        System.out.println(pen);
    }
}

Now let's see <? super T> in action:

public static class Animal {
    public String toString() {
        return getClass().getSimpleName();
    }
}
public static class Rat extends Animal {}
public static class Lion extends Animal {}
public static class Cage<T extends Animal> { /* above */ }

public static void main(String[] args) {
    Cage<Animal> animals = new Cage<Animal>();
    Cage<Lion> lions = new Cage<Lion>();
    animals.add(new Rat()); // OK to put a Rat into a Cage<Animal> 
    lions.add(new Lion());
    lions.transferTo(animals); // invoke the super generic method
    animals.showAnimals();
}

Output:

[Rat, Lion]



Another important concept is that while it is true that:

Lion instanceof Animal // true

it is not true that

Cage<Lion> instanceof Cage<Animal> // false

It this were not the case, this code would compile:

Cage<Animal> animals;
Cage<Lion> lions;
animals = lions; // This assignment is not allowed
animals.add(rat); // If this executed, we'd have a Rat in a Cage<Lion>

这篇关于在泛型中扩展的超级和隐藏的有用示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆