Java 如何返回列表<;Impl>;对于列表<;界面>;

Java 如何返回列表<;Impl>;对于列表<;界面>;,java,Java,下面的代码非常无用,没有经过测试。它只应该解释问题。 我想对应用程序隐藏实现类,但定义层次结构 给定以下接口 public interface RowType { Integer getSumFromHere(); } public interface TableType { List<RowType> getRows(); } 公共接口行类型{ 整数getSumFromHere(); } 公共接口表类型{ List getRows(); } 实施人 publi

下面的代码非常无用,没有经过测试。它只应该解释问题。 我想对应用程序隐藏实现类,但定义层次结构

给定以下接口

public interface RowType {
    Integer getSumFromHere();
}

public interface TableType {
    List<RowType> getRows();
}
公共接口行类型{
整数getSumFromHere();
}
公共接口表类型{
List 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;
    }  
}
公共类RowImpl实现RowType{
私有整数值=0;
私有RowImpl nextRow;
public RowImpl someFunctionNotInInterface()中的函数{
下一步返回;
}
@凌驾
公共整数getSumFromHere(){
return nextRow==null?值:value+nextRow.getSumFromHere();
}
}
公共类TableImpl实现TableType{
List implList=新建ArrayList();
公共无效doSomethingOnImpl(){
for(RowImpl行:implList){
row.someFunctionNotInInterface();
}
}
@凌驾
公共列表getRows(){
返回列表;
}  
}
getRows()的实现会导致错误“无法从列表转换为列表” 事实上,它保证implist中的每个条目都可以通过接口RowType访问,因此它可以工作


我尝试了
您应该将泛型类型更改为

List<RowType> implList = new ArrayList<>();

您应该将泛型类型更改为

List<RowType> implList = new ArrayList<>();

最简单的解决方案是键入并转换列表元素:

public class TableImpl implements TableType {

    List<RowImpl> implList = new ArrayList<>();

    @Override
    public List<RowType> getRows() {
        return implList.stream().map(e -> (RowType) e).collect(Collectors.toList());
    }  
}
通过这种方式,您的实现类可以通过以下方式实现此版本的接口来使用
RowImpl

public class TableImpl implements TableType<RowImpl> {

    List<RowImpl> implList = new ArrayList<>();

    @Override
    public List<RowImpl> getRows() {
        return implList;
    }  
}
公共类TableImpl实现TableType{
List implList=新建ArrayList();
@凌驾
公共列表getRows(){
返回列表;
}  
}

最简单的解决方案是键入并转换列表元素:

public class TableImpl implements TableType {

    List<RowImpl> implList = new ArrayList<>();

    @Override
    public List<RowType> getRows() {
        return implList.stream().map(e -> (RowType) e).collect(Collectors.toList());
    }  
}
通过这种方式,您的实现类可以通过以下方式实现此版本的接口来使用
RowImpl

public class TableImpl implements TableType<RowImpl> {

    List<RowImpl> implList = new ArrayList<>();

    @Override
    public List<RowImpl> getRows() {
        return implList;
    }  
}
公共类TableImpl实现TableType{
List implList=新建ArrayList();
@凌驾
公共列表getRows(){
返回列表;
}  
}

implist
是一个
列表
,应该只包含
行impl
实例

返回的
列表
有一个
add(RowType)
方法,例如,该方法可用于添加非
RowImpl
RowType
实例

因此,
List
不是
List
的超类型,如果要返回它,必须强制转换
implist

同时,您应该确保它没有被调用方修改,因此它实际上只能包含
rowinpl
实例

Collections.unmodifiableList()方法执行以下两项任务:

@Override
public List<RowType> getRows() {
    return Collections.unmodifiableList(implList);
}  
@覆盖
公共列表getRows(){
返回集合。不可修改列表(implList);
}  

implist
是一个
列表
,应该只包含
行impl
实例

返回的
列表
有一个
add(RowType)
方法,例如,该方法可用于添加非
RowImpl
RowType
实例

因此,
List
不是
List
的超类型,如果要返回它,必须强制转换
implist

同时,您应该确保它没有被调用方修改,因此它实际上只能包含
rowinpl
实例

Collections.unmodifiableList()方法执行以下两项任务:

@Override
public List<RowType> getRows() {
    return Collections.unmodifiableList(implList);
}  
@覆盖
公共列表getRows(){
返回集合。不可修改列表(implList);
}  

为什么不按它应该包含的行类型参数化
getRows
?您可以简单地强制转换列表。但是你真的有理由使用
List
而不是
List
?@GiacomoAlzetta:是的,我必须拥有完整的实现问题:你为什么不把
TableType
作为一个通用接口<代码>接口表类型{List getRows();}
这应该可以解决所有问题…为什么不按它应该包含的行类型参数化
getRows
?您可以简单地强制转换列表。但是你真的有理由使用
List
而不是
List
?@GiacomoAlzetta:是的,我必须拥有完整的实现问题:你为什么不把
TableType
作为一个通用接口<代码>接口表类型{List getRows();}这应该可以解决您遇到的所有问题…请遵循解释泛型类型多态性的链接:@Glains是的,对,我忘了澄清我必须在实现中访问Impl定义。当我以行类型维护列表时,我无法再访问非接口方法。请遵循此链接,该链接解释泛型类型的多态性:@Glains是的,对,我忘了澄清我必须在实现中访问Impl定义。当我将列表维护为RowType时,我无法再访问非接口方法。谢谢,这是我不知道的一点。现在很清楚为什么它不能工作了。谢谢,这是我不知道的一点。现在很清楚为什么它不能工作了。