Java泛型问题:符合类型要求的扩展类不被接受求助
你的核心问题在于KeyedBidirectionalStructure的泛型约束定义不符合实际继承逻辑:
原约束要求CHILD extends KeyedStructure<K, KeyedBidirectionalStructure<K, PARENT, CHILD>>,但实际你的CHILD类(比如Task或Group)继承的是KeyedStructure<K, PARENT>(例如KeyedStructure<String, Group>),而非KeyedStructure<K, KeyedBidirectionalStructure<K, PARENT, CHILD>>,两者的泛型参数不匹配,导致编译器报错。
本质上你需要的是递归泛型约束:让双向结构自身作为父类型,同时子类型的父对象类型指向这个双向结构。
重新定义KeyedBidirectionalStructure的泛型约束,引入SELF参数指代当前双向结构类型,确保子类型的父对象类型与双向结构自身一致:
// 基础抽象类:存储父对象 abstract class Structure<T> { protected T parent; public Structure(T parent) { this.parent = parent; } } // 带键的结构:继承Structure,新增键属性 abstract class KeyedStructure<K, V> extends Structure<V> { protected K key; public KeyedStructure(K key, V parent) { super(parent); this.key = key; } } // 双向带键结构:递归约束SELF和CHILD abstract class KeyedBidirectionalStructure<K, SELF extends KeyedBidirectionalStructure<K, SELF, CHILD>, CHILD extends KeyedStructure<K, SELF>> extends KeyedStructure<K, SELF> { protected List<CHILD> children; public KeyedBidirectionalStructure(K key, SELF parent) { super(key, parent); this.children = new ArrayList<>(); } // 添加子节点的方法 public void addChild(CHILD child) { children.add(child); } }
场景1:Group作为双向结构,Task作为子节点
class Task extends KeyedStructure<String, Group> { public Task(String key, Group parent) { super(key, parent); } } class Group extends KeyedBidirectionalStructure<String, Group, Task> { public Group(String key, Group parent) { super(key, parent); } }
此时Task继承KeyedStructure<String, Group>,符合CHILD extends KeyedStructure<K, SELF>(SELF即Group)的约束;Group继承KeyedBidirectionalStructure<String, Group, Task>,也满足SELF extends KeyedBidirectionalStructure<K, SELF, CHILD>的递归约束。
场景2:Group既是父节点也是子节点(自双向结构)
class Group extends KeyedBidirectionalStructure<String, Group, Group> { public Group(String key, Group parent) { super(key, parent); } }
此时Group同时满足SELF和CHILD的约束:作为SELF继承双向结构,作为CHILD继承KeyedStructure<String, Group>(双向结构的父类正是KeyedStructure<String, Group>)。
- 引入
SELF参数是为了明确双向结构自身的类型,避免泛型参数混淆; - 递归泛型约束在Java中是合法的,常用于实现类型安全的双向关联(比如树形结构、父子关联);
- 修正后的约束确保了子类型的父对象类型与双向结构自身严格一致,符合你“CHILD能将当前类作为父对象存储”的需求。
内容的提问来源于stack exchange,提问作者omzz15

