gpt4 book ai didi

Java 多态性和列表

转载 作者:行者123 更新时间:2023-11-29 07:04:43 25 4
gpt4 key购买 nike

假设我有以下类结构

public abstract class MyClass{}

public class MyClassA extends MyClass{}

public class MyClassB extends MyClass{}

如何创建一个包含 MyClassA 和 MyClassB 元素且没有异议的 MyClass 元素列表?

例如

    List<MyClass> myList = new LinkedList<MyClassA>();

最佳答案

根据您的需要,您有多种选择。您可以使用普通 List<MyClass>类型对象。这允许您添加类型的对象 MyClassAMyClassB .您不能将 List 类型对象设置为类型为 List<MyClass> 的变量。 .这是由于称为方差 的概念。大多数支持泛型(参数化多态性)的编程语言中存在三种类型的变体。

不变性

不变性不允许在任一方向上偏离类型。默认情况下,Java 中的泛型就是这种情况,这就是为什么您不能分配 List<MyClassA> 的原因。到 List<MyClass> 的变量.想象一下以下场景:

List<MyClassA> listA = new List<MyClassA>();
List<MyClass> list = (List<MyClass>) listA; // Produces a compilation error...
list.add(new MyClassB()); // ... because this would be a big no-no

协方差

协变允许您使用指定的参数类型或其任何子类型。在 Java 中,您使用 extends 关键字来指定协方差:List<? extends MyClass> .允许将 List 类型的对象赋值给这样的变量。但是,使用协变,您不能在没有显式转换的情况下将任何对象添加到您的通用对象实例。那就是你不能做以下事情:

List<? extends MyClass> list = new LinkedList<MyClassA>();
list.add(new MyClassA());

这只是合乎逻辑的。毕竟,您无法确切地知道您正在处理的是什么类型的列表。它也可能是 List<MyClassB> .

逆变

逆变是协方差的反面,使用 super 关键字指定:List<? super MyClassA> .允许分配 List<MyClass> (但不是 List<MyClassB> )类型对象到这样的变量中。通过逆变,您可以添加指定类型参数的任何子类型(类型层次结构中的下限)。也就是说,它可以执行以下操作:

List<? super MyClass> list = new LinkedList<MyClass>();
list.add(new ChildA());

但是,您无法确切知道对象是什么类型的列表。也就是说,您只能直接将存储在列表中的对象分配给类型为 Object 的变量,而无需显式强制转换:

Object o = list.get(0);
if (o instanceof MyClassA) {
MyClassA mca = (MyClassA) o;
//...
}

我希望这有助于澄清一些事情。

关于Java 多态性和列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21118680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com