简体   繁体   中英

Subclass implementations of generics methods

I'm trying to make a parent class for converters avoiding repeated code, so I started doing the java abstract class I provide here:

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;
    }
}

The problem is when coming to subclassing. When I make a subclass extending this class and replace the type of the input parameter called 'input' in the method signature to override either toDto() or toUIO() like this:

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

it appears a message:

The method toDto(SomeTypeUIO) of type SubclassConverter must override or implement a supertype method

If I replace in the the first type:

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

it appears this warning:

The type parameter SomeTypeUIO is hiding the type

which obviously is what I don't want.

I have tried parameterizing AbstractUIConverter but this is worse. I also have tried messing with "extends" inside syntax.

My goal is to define the types in the subclass, so the functions for converting lists are all made in the parent.

I would appreciate help and advice, or some resources for looking in the web.

The right approach would be:

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;
  }
}

You already have a distinction in your method call how to transform your data.

< 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;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM