微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java泛型和类层次结构

如何解决Java泛型和类层次结构

| 我遇到这种情况,我尝试创建一个示例,并想看看是否有任何优雅的方法来修复它。 假设我有一些可显示的接口,并实现了类:Person和Car,并且我声明了通用的Converter类,如下所示:
public interface Converter<T extends displayable> {
    boolean canConvert(displayable o);
    String convert(T o);
    T decode(String s);
    boolean canRevert(String s);
}
假设我有这个实现
public class CarConverter implements Converter<Car> { ... }
public class PersonConverter implements Converter<Person> { ... }
现在,在我的使用中,我有一个displayable列表和一个转换器列表,我想转换和还原displayable:
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);
                }                
            }
        }
令人讨厌的一点是,我不得不声明一个Converter列表,从而失去了泛型。
List<Converter>
如果尝试声明,则会收到语法错误
List<Convert<displayable>>
然后我收到很多警告。     

解决方法

        您可以这样做,您只需要对列表声明进行一些更改:
List<Converter<? extends Displayable>> list = ...
这将为您工作。这里要记住的关键是,您不能依赖嵌套类型参数中的继承,需要使用
extends
声明扩展名。 如果您有8个实例,则只能将9个实例添加到该列表中,而不能将10个实例添加到该列表中。     ,        看起来转换器只是在制作可显示内容的字符串表示形式。如果是这种情况,我认为您真正想做的就是为每个Displayable重写toString()方法,并为每个参数提供一个以显示字符串作为参数的构造函数。然后,您不必担心为Displayable的每个实现实现单独的Converter。所以一个人看起来像:
public class Person implements Displayable {
    public Person(String display) {
        // Make a Person from a display
    }

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

    ...
}
    ,        这可能很la脚,但是在这种情况下您根本不需要泛型。由于您已经使用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 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);    
}
还是我缺少的仿制药有什么优势? 一个更漂亮的解决方案是将转换器代码包含在Displayable类中。如果每种类型只有一个转换器,那就更好了。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。