以下代码非常没用,未经测试。它仅应解释问题。
我想从应用程序中隐藏实现类,但要定义层次结构。
给定以下接口
public interface RowType {
Integer getSumFromHere();
}
public interface TableType {
List<RowType> getRows();
}
实施者
public class RowImpl implements RowType {
private Integer value = 0;
private RowImpl nextRow;
public RowImpl someFunctionNotInInterface() {
return nextRow;
}
@Override
public Integer getSumFromHere() {
return nextRow == null ? value : value + nextRow.getSumFromHere();
}
}
public class TableImpl implements TableType {
List<RowImpl> implList = new ArrayList<>();
public void doSomethingOnImpl (){
for(RowImpl row : implList) {
row.someFunctionNotInInterface();
}
}
@Override
public List<RowType> getRows() {
return implList;
}
}
getRows()的实现导致错误
"cannot convert from List<RowImpl> to List<RowType>"
实际上,它保证了implList中的每个条目都可以通过RowType接口访问,因此它可以工作。
我尝试了
<? extends RowType>
,但这与TableType接口不兼容。当然,我可以通过复制列表
return new ArrayList<>(implList);
来简单地解决问题,但这与引用类所拥有的列表并不相同。是否有解决方案,还是设计完全错误?
编辑:在TableImpl中添加了函数,该函数阐明了为什么列表基于RowImpl而不是RowType构建。
最佳答案
implList
是List<RowImpl>
,并且应仅包含RowImpl
实例。
例如,您返回的List<RowType>
具有add(RowType)
方法,该方法可用于添加非RowType
的RowImpl
实例。
因此,List<RowType>
不是List<RowImpl>
的超类型,如果要返回implList
,则必须强制转换。
同时,您应确保调用者未修改它,以便它实际上只能包含RowImpl
实例。
Collections.unmodifiableList()方法可以完成以下两项工作:
@Override
public List<RowType> getRows() {
return Collections.unmodifiableList(implList);
}