列表的连续继承

use*_*497 2 java inheritance list arraylist

我有一个List结构设置如下:

List<List<Value>> l = new RowList();
Run Code Online (Sandbox Code Playgroud)

这给出了一个"Type mismatch: Cannot convert from RowList to List<List<Value>>"错误.实施如下:

public class RowList extends ArrayList<ValueList>
public class ValueList extends ArrayList<Value>
Run Code Online (Sandbox Code Playgroud)

Value是我的代码库中的一个对象.为什么这不起作用?当我有这个时,一切正常:

public class RowList extends ArrayList<List<Value>>
Run Code Online (Sandbox Code Playgroud)

对于我正在进行的大学任务,我们的讲师编写的代码通过调用List<List<Value>>在我的代码中返回一个方法,然后添加List<Value>到该列表的方法来工作.由于该程序旨在实现数据库,因此有许多要求,例如键值不会出现多次等.要检查这是否发生,我需要能够有一个ValueList类或类似的东西所以我可以扩展add()方法来检查这些要求.

现在听起来这不是正确的做事方式,但我真的没有任何选择,因为我们不允许改变执行此操作的代码.我相信这个想法是让我们考虑仿制药.

JB *_*zet 8

首先创建集合的子类是个坏主意.坚持使用标准实现,并使用组合而不是继承.

现在要理解为什么这不编译,这就是为什么,用一个简短的例子.假设您想要做的事情是可能的并且编译,那么您可以这样做:

RowList rowList = new RowList();
List<List<Value>> listOfLists = rowList;
listOfLists.add(new LinkedList<Value>());
Run Code Online (Sandbox Code Playgroud)

虽然RowList应该ValueList仅包含实例,但是你会有一个LinkedList<Value>内部,破坏了程序的类型安全性和正确性.

  • 使用合成是在不破坏List合同的情况下执行此操作的唯一方法.List不应该拒绝任何添加的元素.将列表包装到一个自定义类中,提供一个抛出一些InvalidObjectException的add()方法.不要扩展List来做到这一点:你会打破Liskov原则.此外,使用继承是一种可靠的失败方法,并且在使用下一版本的JDK时会有代码中断,因为有任何方法可以将元素添加到列表中(add,addAll,iterator等) (2认同)