Java 在客户端代码中使用类型处理多个类

Java 在客户端代码中使用类型处理多个类,java,generics,type-safety,java-5,Java,Generics,Type Safety,Java 5,假设我有以下的课程 class A {} class B {} abstract class ParentClass<T> { abstract void accept(T t); } class Child1 extends ParentClass<A> { void accept(A a) {} } class Child2 extends ParentClass<B> { void accept(B b) {}

假设我有以下的课程

class A {} 
class B {} 

abstract class ParentClass<T> {
    abstract void accept(T t);
} 

class Child1 extends ParentClass<A> {
    void accept(A a) {} 
} 

class Child2 extends ParentClass<B> {
    void accept(B b) {} 
} 
class A{}
B类{}
抽象类父类{
抽象无效接受(T);
} 
类Child1扩展了ParentClass{
无效接受(A){}
} 
类Child2扩展了ParentClass{
无效接受(B){}
} 
现在,如果我有一个客户端代码,我想让child1和child2的实例都映射到映射中的字符串(并且)还使用accept方法,这似乎是不可能的,我明白了原因。有更好的工作吗

我的客户端代码看起来像

class Client {
    Map<String, ParentClass<?>> map = new HashMap<>();

    public Client() {
       map.put("C1", new Child1());
       map.put("C2", new Child2());
    } 

    void callAccept(String type, Object o) {
        map.get(type).accept(o); //error
    } 

} 
类客户端{
Map“更好”取决于您想要实现的目标。我理解您的问题,您只希望能够编译代码并理解它。许多变体都是可能的,“最佳”取决于您正在解决的业务问题

如果没有代码可能解决的业务问题,下面是编译时不会出错的代码。我修复了代码中的几个错误:

//ParentClass.java
类基{}
类扩展了基{}
类B扩展了基{}
抽象类父类{
抽象父类accept(Base);
}
Child1类扩展了ParentClass,特别是为了精确定义什么是允许的。实际上,在不迷失数学的情况下,上面的一般准则是处理泛型的一些注意事项

有关更多信息,请阅读Joshua Bloch在“有效Java”中关于泛型容器的部分。我相信他没有提到范畴理论,这是好的


如果您对“刚好够”类型理论感兴趣,请阅读。

缺少
accept
的返回类型。
new Child1()中也没有菱形
因为类没有参数化。奇怪的是,将代码从您的计算机复制到如此多的东西;)您的
accept
没有返回类型。此外,您正在失去一些类型安全性。您可以做的一件事是让accept方法接受
对象
,然后在e
Child1
Child2
的实现。您还可以在地图中使用
A
B
实现一个通用界面。这完全取决于您想要实现什么以及您想要如何使用该地图。@azro,我没有从我的计算机复制代码。我是从手机上键入问题的。您呢真的还在使用Java 5吗?考虑到Java 5已经有17年的历史了,我认为可以假设泛型是给定的。您只需要添加这样一个旧版本,就有一些特殊的东西,只需要使用Java 5的特性。这里的问题是accept方法应该仍然在父类中接受T,而不是在基类中接受T。我看到过以这种方式编写的代码在一些代码库和客户机代码中,他们在映射中使用原始类型只是为了避免调用accept方法时语句中的错误……正如我在示例中使用通配符只是为了展示问题。正如我所说,许多排列是可能的。你问了一个非常普遍的问题,整本书都是关于这是一个主题。