泛型方法的子类实现

时间:2017-08-10 10:25:55

标签: java generics inheritance

我正在尝试为转换器创建一个避免重复代码的父类,所以我开始做我在这里提供的java抽象类:

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

public abstract class AbstractUIConverter {
    protected abstract <UIO, DTO> DTO toDto(final UIO input);

    protected abstract <DTO, UIO> UIO toUIO(final DTO input);

    protected <UIO, DTO> List<DTO> toDtoList(final List<UIO> inputList) {
        return convertList(inputList, true);
    }

    protected <DTO, UIO> List<UIO> toUIOList(final List<DTO> inputList) {
        return convertList(inputList, false);
    }

    private <I, O> List<O> convertList(final List<I> inputList, final boolean toDto) {
        List<O> returnList;
        if(CollectionUtils.isNotEmpty(inputList)) {
            returnList = new ArrayList<O>(inputList.size());
            O temp;
            for (final I inputElem : inputList) {
                if(toDto) {
                    temp = toDto(inputElem);
                } else {
                    temp = toUIO(inputElem);
                }
                returnList.add(temp);
            }
        } else {
            returnList = new ArrayList<O>(0);
        }
        return returnList;
    }
}

问题在于进入子类化。当我创建一个子类来扩展这个类并替换方法签名中名为'input'的输入参数的类型来覆盖toDto()或toUIO()时这样:

@Override
protected <UIO, DTO> DTO toDto(SomeTypeUIO input) {

它出现了一条消息:

  

SubclassConverter类型的toDto(SomeTypeUIO)方法必须覆盖或实现超类型方法

如果我替换第一种类型:

protected <SomeTypeUIO, DTO> DTO toDto(SomeTypeUIO input) {

出现此警告:

  

类型参数SomeTypeUIO隐藏了类型

这显然是我不想要的。

我尝试过参数化AbstractUIConverter,但情况更糟。我也试过在语法内部弄乱“扩展”。

我的目标是在子类中定义类型,因此转换列表的函数都是在父类中完成的。

我希望得到帮助和建议,或者在网上查看的一些资源。

1 个答案:

答案 0 :(得分:1)

正确的方法是:

public abstract class AbstractUIConverter<UIO, DTO> {
  protected abstract DTO toDto(final UIO input);

  protected abstract UIO toUIO(final DTO input);

  protected List<DTO> toDtoList(final List<UIO> inputList) {
    return convertList(inputList, this::toDto);
  }

  protected List<UIO> toUIOList(final List<DTO> inputList) {
    return convertList(inputList, this::toUIO);
  }

  private <I, O> List<O> convertList(final List<I> inputList, final Function<I, O> function) {
    if(inputList.isEmpty()) {
      return Collections.emptyList();
    }
    List<O> returnList = new ArrayList<>(inputList.size());
    for(I input : inputList) {
      returnList.add(function.apply(input));
    }
    return returnList;
  }
}

您的方法调用已经区分了如何转换数据。

&LT; Java 8:

public abstract class AbstractUIConverter<UIO, DTO> {
  protected abstract DTO toDto(final UIO input);

  protected abstract UIO toUIO(final DTO input);

  protected List<DTO> toDtoList(final List<UIO> inputList) {
    return convertList(inputList, new Function<UIO, DTO>() {
      @Override
      public DTO apply(UIO input) {
        return AbstractUIConverter.this.toDto(input);
      }
    });
  }

  protected List<UIO> toUIOList(final List<DTO> inputList) {
    return convertList(inputList, new Function<DTO, UIO>() {
      @Override
      public UIO apply(DTO input) {
        return AbstractUIConverter.this.toUIO(input);
      }
    });
  }

  private <I, O> List<O> convertList(final List<I> inputList, final Function<I, O> function) {
    if(inputList.isEmpty()) {
      return Collections.emptyList();
    }
    List<O> returnList = new ArrayList<>(inputList.size());
    for(I input : inputList) {
      returnList.add(function.apply(input));
    }
    return returnList;
  }
}