Java泛型和类层次结构

Java泛型和类层次结构,java,generics,Java,Generics,我有这种情况,我试图创建一个例子,并想看看是否有任何优雅的方式来解决它 假设我有一些可显示的接口和实现类:Person和Car,并且我有如下声明的通用转换器类: public interface Converter<T extends Displayable> { boolean canConvert(Displayable o); String convert(T o); T decode(String s); boolean canRevert(S

我有这种情况,我试图创建一个例子,并想看看是否有任何优雅的方式来解决它

假设我有一些可显示的接口和实现类:Person和Car,并且我有如下声明的通用转换器类:

public interface Converter<T extends Displayable> {
    boolean canConvert(Displayable o);
    String convert(T o);
    T decode(String s);
    boolean canRevert(String s);
}
公共接口转换器{
布尔转换(可显示o);
字符串转换;
T解码(字符串s);
布尔值(字符串s);
}
假设我有这个的实现

public class CarConverter implements Converter<Car> { ... }
公共类CarConverter实现转换器{…}

公共类PersonConverter实现转换器{…}
现在在我的使用中,我有一个可显示列表和一个转换器列表,我想转换和还原可显示列表:

List<Displayable> ds = new ArrayList<Displayable>();
ds.add(new Person("ma",12));
ds.add(new Person("fa",43));
ds.add(new Car());
ds.add(new Car());
ds.add(new Person("Sol",58));

List<Converter>cs = new ArrayList<Converter>();
cs.add(new CarConverter());
cs.add(new PersonConverter());

        ArrayList<String> displays = new ArrayList<String>();
        for(Displayable d:ds) {
            for(Converter c:cs) {
                if(c.canConvert(d)) {
                    displays.add(c.convert(d));
                    break;
                }
            }
        }

        List<Displayable> ret = new ArrayList<Displayable>();

        for(String display : displays) {
            for(Converter c:cs) {
                if(c.canRevert(display)) {
                    Displayable d = c.decode(display);
                    ret.add(d);
                }                
            }
        }
List ds=new ArrayList();
ds.增补(新人士(“ma”,12));
ds.添加(新人员(“fa”,43));
ds.添加(新车());
ds.添加(新车());
ds.添加(新人员(“Sol”,58));
Listcs=newarraylist();
添加(新的CarConverter());
添加(新PersonConverter());
ArrayList displays=新建ArrayList();
用于(可显示的d:ds){
用于(转换器c:cs){
如果(c.canConvert(d)){
显示。添加(c.convert(d));
打破
}
}
}
List ret=new ArrayList();
用于(字符串显示:显示){
用于(转换器c:cs){
如果(c.canRevert(显示)){
可显示d=c.解码(显示);
再加上(d);
}                
}
}
令人恼火的是,我不得不声明一个列表转换器,失去了泛型

List<Converter>
列表
如果我试图声明,就会出现语法错误

List<Convert<Displayable>>
列表

然后我收到了很多警告。

看起来转换器只是在对可显示内容进行字符串表示。如果是这样的话,我认为您真正想要做的是为每个displaybable重写toString()方法,并为每个displaybable提供一个以display字符串作为参数的构造函数。这样,您就不必担心为每个Displayable的实现实现一个单独的转换器。所以一个人看起来像:

public class Person implements Displayable {
    public Person(String display) {
        // Make a Person from a display
    }

    public String toString() {
        // Make a display from a person
    }

    ...
}

您可以这样做,只需对列表声明稍作更改:

List<Converter<? extends Displayable>> list = ...

List这可能很蹩脚,但在这种情况下根本不需要泛型。因为您已经使用了canConvert和canRevert,所以不需要额外的编译时类型检查

我的快速修复代码:

public static void main(String[] args) {
    List<Displayable> ds = new ArrayList<Displayable>();
    ds.add(new Person("ma", 12));
    ds.add(new Person("fa", 43));
    ds.add(new Car());
    ds.add(new Car());
    ds.add(new Person("Sol", 58));

    ArrayList<Converter> cs = new ArrayList<Converter>();
    cs.add(new CarConverter());
    cs.add(new PersonConverter());

    ArrayList<String> displays = new ArrayList<String>();
    for (Displayable d : ds) {
        for (Converter c : cs) {
            if (c.canConvert(d)) {
                displays.add(c.convert(d));
                break;
            }
        }
    }

    List<Displayable> ret = new ArrayList<Displayable>();

    for (String display : displays) {
        for (Converter c : cs) {
            if (c.canRevert(display)) {
                Displayable d = c.decode(display);
                ret.add(d);
            }
        }
    }
}

包转换

public interface Converter {
    boolean canConvert(Displayable o);
    String convert(Displayable o);
    Displayable decode(String s);
    boolean canRevert(String s);    
}
或者我缺少的泛型有什么优势?
一个更漂亮的解决方案是在可显示类中包含转换器代码。如果你对每种类型只有一个转换器,那就更好了。

为什么你认为列表不如列表那么具体?你有接口名转换器而不是转换器。你可以声明“代码>列表> Cs = NealAlyList > <代码>,但是你必须担心<代码>捕获< /Cord>。只是为了解释这个问题,我在现实生活中的用法要复杂得多,泛型在这种情况下非常有用。罗布的回答是最优雅的,他应该考虑到这一点。我也尝试了罗布的解决方案,但失败了。示例代码仍然给我滥用泛型的感觉,但我相信您的实际使用有很好的理由。明天我得再试试罗布的解决方案,我忘了一些小事。
public class CarConverter implements Converter {

    @Override
    public boolean canConvert(Displayable o) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean canRevert(String s) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public String convert(Displayable o) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Car decode(String s) {
        // TODO Auto-generated method stub
        return null;
    }

}
public interface Converter {
    boolean canConvert(Displayable o);
    String convert(Displayable o);
    Displayable decode(String s);
    boolean canRevert(String s);    
}