我对Java编程非常陌生,并且遇到了一个设计问题。目前,我得到的是以下内容:

public class MyFactory {

    private MyFactory(){
        //hidden constructor
    }

    public static ImageFilter getInstance(String filterType){
        if(filterType == “foo“){
            return new FooFilter();
        }
        return null;
    }
}

public abstract class ImageFilter {
    public abstract Bitmap filterImage(byte[] data);

    //some other stuff
}

public class FooFilter extends ImageFilter {
    public C filterImage(byte[] data){
        //want to apply filterImageA or filterImageB depending what I put in
        //at (*) and (**)
    }

    private A filterImageA(byte[] data){
        //
    }

    private B filterImageB(byte[] data){
       //
    }
}

void main(byte[] data) {
    ImageFilter bar = MyFactory.getInstance(“foo“);
    BitmapType1 myBitmap = bar.filterImage(byte[] data);   //(*)
    BitmapType2 myBitmap2 = bar.filterImage(byte[] data);   //(**)
}


在主要方法中,我知道结果类型是什么。如果是BitmapType1,则必须应用filterImageA。如果是BitmapType2,则必须使用filterImageB。有通用的方法可以做到吗?我读过有关泛型的知识,但对在这种特殊情况下如何使用泛型一无所知。我希望那不要太混乱。也许整个方法都是胡扯。欢迎提出更好的建议!

最佳答案

@Dima的答案是正确的。但是您也可以使ImageFilter对泛型更友好:

public class MyFactory {

    private MyFactory(){
        //hidden constructor
    }

    public static ImageFilter getInstance(String filterType){
        if(filterType == “foo“){
            return new FooFilter();
        }
        return null;
    }
}

public abstract class ImageFilter {
    public abstract <T extends Bitmap> T filterImage(byte[] data, Class<T> clazz);

    //some other stuff
}

public class FooFilter extends ImageFilter {
    public <T extends Bitmap> T filterImage(byte[] data, Class<T> clazz){
        if (BitmapType1.class.isAssignableFrom(clazz)) {
            return this.filterImageA(data);
        } else if (BitmapType2.class.isAssignableFrom(clazz)) {
            return this.filterImageB(data);
        }
        return null; // or better throw runtime exception
    }

    private BitmapType1 filterImageA(byte[] data){
        //
    }

    private BitmapType2 filterImageB(byte[] data){
       //
    }
}

void main(byte[] data) {
    ImageFilter bar = MyFactory.getInstance(“foo“);
    BitmapType1 myBitmap = bar.filterImage(byte[] data, BitmapType1.class);
    BitmapType2 myBitmap2 = bar.filterImage(byte[] data, BitmapType2.class);
}


注意:如果BitmapType1继承(直接或不继承)BitmapType2或反之,则首先需要检查层次结构中最具体的类:

        if (BitmapType1.class.isAssignableFrom(clazz)) { // BitmapType1 type more concrete
            return this.filterImageA(data);
        } else if (BitmapType2.class.isAssignableFrom(clazz)) { // BitmapType2 type more general
            return this.filterImageB(data);
        }

10-07 23:23