全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-10 7 分钟 ✍️ juanwangdev

泛型与继承

泛型类型之间不存在继承关系,这是理解泛型类型安全的关键。

泛型类型不继承

Java
// 错误理解:List<String> 不是 List<Object> 的子类
List<String> strings = new ArrayList<>();
List<Object> objects = strings;  // 编译错误

// 原因:如果允许,会有类型安全问题
// objects.add(new Integer(1));  // 放入 Integer
// String s = strings.get(0);    // 取出 Integer,类型错误!

泛型不变性:List 和 List 没有继承关系,互不兼容。

类型安全示例

Java
// 如果允许赋值(假设)
List<String> strings = new ArrayList<>();
List<Object> objects = strings;  // 如果编译通过

objects.add(new Integer(100));   // 向 Object 列表添加 Integer
String s = strings.get(0);       // 从 String 列表取出 Integer → 类型错误!

// Java 编译器禁止这种赋值,保证类型安全

数组的协变

数组是协变的(有继承关系):

Java
// 数组协变:String[] 是 Object[] 的子类
String[] strings = new String[10];
Object[] objects = strings;  // 允许

objects[0] = new Integer(100);  // 运行时抛 ArrayStoreException

数组协变问题:编译通过但运行时出错。泛型不变性避免了这种问题。

特性数组泛型
继承关系协变(有继承)不变(无继承)
类型安全运行时检查编译期检查
错误时机运行时抛异常编译期禁止

类型继承示例

Java
// 类型参数的继承关系不影响泛型类继承
class Animal {}
class Dog extends Animal {}

// Dog 是 Animal 的子类
Dog dog = new Dog();
Animal animal = dog;  // ✅ 允许

// 但 List<Dog> 不是 List<Animal> 的子类
List<Dog> dogs = new ArrayList<>();
List<Animal> animals = dogs;  // ❌ 编译错误

使用通配符实现"继承"

Java
List<Dog> dogs = new ArrayList<>();

// 使用上界通配符
List<? extends Animal> animals = dogs;  // ✅ 允许

// 但只能读取,不能添加
Animal a = animals.get(0);  // ✅ 读取
animals.add(new Dog());     // ❌ 不能添加

泛型类继承规则

泛型类之间的继承

Java
// 泛型类继承
public class Box<T> {}
public class SpecialBox<T> extends Box<T> {}  // 继承泛型类

// 指定具体类型继承
public class StringBox extends Box<String> {}  // 指定类型

实现泛型接口

Java
public interface Generator<T> {}

// 指定类型实现
public class StringGenerator implements Generator<String> {}

// 保留泛型实现
public class GenericGenerator<T> implements Generator<T> {}

协变与逆变

概念说明Java 实现
协变子类关系保留<? extends T>
逆变子类关系反转<? super T>
不变无继承关系泛型默认不变
Java
// 协变:List<? extends Animal> 可接收 List<Dog>
List<? extends Animal> animals = new ArrayList<Dog>();  // ✅

// 逆变:List<? super Dog> 可接收 List<Animal>
List<? super Dog> list = new ArrayList<Animal>();  // ✅

要点总结

  • 泛型不变性:List 不是 List 的子类
  • 类型参数的继承不影响泛型类继承
  • 数组协变,泛型不变
  • 协变用 <? extends T>,逆变用 <? super T>
  • 泛型在编译期保证类型安全,数组在运行时检查
  • 泛型类可继承泛型类或指定类型继承

📝 发现内容有误?点击此处直接编辑

← 上一篇 泛型与数组
下一篇 → 泛型接口
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库