Assign a subclass of a Generic class to a super class of this class

后端 未结 5 2104
心在旅途
心在旅途 2020-12-11 19:58

I have couple of supplied interfaces

public interface Finder,T extends Item> {
    public S find(S s, int a);
}

public interf         


        
5条回答
  •  一整个雨季
    2020-12-11 20:08

    As discussed in the comments, your design necessitates that the getCopy method return the "self type" - that is, a BlueStack implementation would be expected to return a BlueStack from its getCopy, and RedStack should return a RedStack etc.

    Unfortunately, there is no way to express the "self type" in Java. As zhong.j.yu points out, a recursive type parameter comes close, for example:

    //not recommended!
    public interface Stack, T extends Item> {
        S getCopy();
    }
    

    But as zhong.j.yu mentions this is unintuitive and would still fail to prevent a BlueStack from "lying" and returning a RedStack from its getCopy.

    Instead, I recommend a redesign. Try decoupling the responsibility of copying stacks from the Stack type itself. For example:

    public interface StackCopier, T extends Item> {
    
        S copy(S original);
    }
    

    If implementations of StackCopier need access to private members of their respective Stacks, consider making them nested classes, for example:

    class BlueStack implements Stack {
    
        ...
    
        static class Copier implements StackCopier, T> {
    
            @Override
            public BlueStack copy(BlueStack original) {
    
                ...
            }
        }
    

    Of course SimpleFinder would need to be changed to either have a StackCopier field or take one as a new parameter of find:

    private final StackCopier copier = ...;
    
    public S find(S stack, int a) {
    
         S stackCopy = copier.copy(stack);
    
         ...
    
         return stackCopy;
    }
    

提交回复
热议问题