Java中的泛型继承
泛型继承是一种允许类或接口继承其他泛型类或接口的特性,它能够在继承时保持类型参数的灵活性或对其进行具体的指定。下面从多个方面介绍泛型继承:
1. 继承泛型类
在继承泛型类时,可以选择保留泛型参数,也可以为其提供具体的类型。
// 定义一个泛型类
class GenericClass<T> {private T value;public GenericClass(T value) {this.value = value;}public T getValue() {return value;}
}// 子类保留泛型参数
class SubClass1<T> extends GenericClass<T> {public SubClass1(T value) {super(value);}
}// 子类为泛型参数提供具体类型
class SubClass2 extends GenericClass<String> {public SubClass2(String value) {super(value);}
}
2. 继承泛型接口
泛型接口的继承与泛型类的继承类似,既可以保留泛型参数,也可以指定具体类型。
// 定义一个泛型接口
interface GenericInterface<T> {T method(T param);
}// 子类保留泛型参数
class ImplClass1<T> implements GenericInterface<T> {@Overridepublic T method(T param) {return param;}
}// 子类为泛型参数提供具体类型
class ImplClass2 implements GenericInterface<Integer> {@Overridepublic Integer method(Integer param) {return param * 2;}
}
3. 限定泛型类型参数
在继承泛型类或接口时,可以对泛型类型参数进行限定,使其必须是某个类的子类或实现某个接口。
// 定义一个泛型类,限定T必须是Number的子类
class NumberGeneric<T extends Number> {private T number;public NumberGeneric(T number) {this.number = number;}public double getValue() {return number.doubleValue();}
}// 子类保留泛型参数,但仍受限于Number的子类
class SubNumberGeneric<T extends Number> extends NumberGeneric<T> {public SubNumberGeneric(T number) {super(number);}
}
4. 多重泛型参数
泛型类或接口可以有多个泛型参数,在继承时需要对每个参数进行处理。
// 定义一个具有两个泛型参数的类
class Pair<K, V> {private K key;private V value;public Pair(K key, V value) {this.key = key;this.value = value;}public K getKey() {return key;}public V getValue() {return value;}
}// 子类保留两个泛型参数
class SubPair<K, V> extends Pair<K, V> {public SubPair(K key, V value) {super(key, value);}
}// 子类为其中一个泛型参数提供具体类型
class StringKeyPair<V> extends Pair<String, V> {public StringKeyPair(String key, V value) {super(key, value);}
}
5. 通配符与泛型继承
在使用泛型类或接口时,可以使用通配符(?
)来表示未知类型,这在泛型继承中也很常见。
// 定义一个泛型类
class Container<T> {private T value;public Container(T value) {this.value = value;}public T getValue() {return value;}
}// 使用通配符的泛型继承
class Processor {public static void process(Container<? extends Number> container) {Number value = container.getValue();System.out.println("Value: " + value);}
}
6. 泛型方法的继承
泛型方法也可以被继承和重写,但需要注意类型参数的一致性。
// 定义一个包含泛型方法的类
class GenericMethodClass {public <T> T genericMethod(T param) {return param;}
}// 子类重写泛型方法
class SubGenericMethodClass extends GenericMethodClass {@Overridepublic <T> T genericMethod(T param) {System.out.println("Processing: " + param);return param;}
}
7. 类型擦除与泛型继承
Java的泛型是通过类型擦除实现的,在运行时泛型类型信息会被擦除。这可能会影响泛型继承的行为,尤其是在处理桥接方法时。
// 类型擦除示例
class ErasureExample<T> {private T value;public T getValue() {return value;}public void setValue(T value) {this.value = value;}
}// 编译后,泛型类型T被擦除,相当于:
class ErasureExample {private Object value;public Object getValue() {return value;}public void setValue(Object value) {this.value = value;}
}
泛型继承是Java泛型机制的重要组成部分,它提供了强大的类型安全和代码复用能力。通过合理使用泛型继承,可以编写出更加灵活、可维护的代码。
8. 扩展阅读extends通配符
- Java中的extends通配符