简体   繁体   English

Java协方差

[英]Java covariance

I'm having a hard time trying to figure this out. 我很难解决这个问题。 Say I have the following code: 说我有以下代码:

class Animal { }
class Mammal extends Animal { }
class Giraffe extends Mammal { }
...
public static List<? extends Mammal> getMammals() { return ...; }
...

public static void main(String[] args) {
    List<Mammal> mammals = getMammals(); // compilation error
}

Why does the assignment result in a compilation error? 为什么分配会导致编译错误? The error is something like: 错误是这样的:

Type mismatch: cannot convert from List<capture#4-of ? extends Mammal> to List<Mammal>

According to my understanding of covariance, the getMammals() method returns a list that will always contain Mammal objects so it should be assignable. 根据我对协方差的理解, getMammals()方法返回一个始终包含Mammal对象的list ,因此它应该是可分配的。 What am I missing? 我想念什么?

Because getMammals could return a List<Giraffe> , and if that was convertable to List<Mammal> then you'd be able to add a Zebra to it. 因为getMammals可以返回List<Giraffe> ,并且如果可以将其转换为List<Mammal>则可以向其中添加Zebra You can't be allowed to add a Zebra to a list of Giraffe , can you? 您不可以将Zebra添加到Giraffe列表中,可以吗?

class Zebra extends Mammal { }

List<Giraffe> giraffes = new List<Giraffe>();

List<Mammal> mammals = giraffes; // not allowed

mammals.add(new Zebra()); // would add a Zebra to a list of Giraffes

Well, it doesn't work like that unfortunately. 好吧,不幸的是,它不是那样工作的。

When you declare getMammals() to return List<? extends Mammal> 当您声明getMammals()返回List<? extends Mammal> List<? extends Mammal> it means it can return List<Mammal> or List<Giraffe> but not List<Animal> List<? extends Mammal>这意味着它可以返回List<Mammal>List<Giraffe>但不能返回List<Animal>

Yours main() should look like this: 您的main()应该如下所示:

public static void main(String[] args) {
    List<? extends Mammal> mammals = getMammals();
    Mammal mammal = mammals.get(0);
}

EDIT: Regarding covariance, that's what is usually meant by that: 编辑:关于协方差,这通常是指:

class Animal {
    public Animal getAnimal() {return this;}
}

class Mammal extends Animal {
    public Mammal getAnimal() {return this;}
}

class Giraffe extends Mammal {
    public Giraffe getAnimal() {return this;}
}

As you can see it allows to overload return type of methods when you overriding the method. 如您所见,当您覆盖方法时,它允许重载方法的返回类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM