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

问题描述

假设我有以下课程

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) {} 
} 

现在,如果我有一个客户端代码,我想将 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
    } 

} 

#更新 1 在示例中添加返回类型,因为我在移动设备上输入问题时错过了。

解决方法

“更好”取决于您想要达到的目标。据我了解您的问题,您只是希望能够编译代码并理解它。可能有多种变化,“最佳”取决于您要解决的业务问题。

如果没有代码可能解决的业务问题,这里是编译没有错误的代码。我修复了您代码中的几个错误:

// ParentClass.java

class Base {}
class A extends Base {}
class B extends Base {}

abstract class ParentClass<T> {
   abstract ParentClass<?> accept(Base base);
}

class Child1 extends ParentClass<A> {
  /* No idea what this is supposed to do,so just return something type-compatible */
  ParentClass<A> accept(Base base) { return this; }
}

class Child2 extends ParentClass<B> {
  /* No idea what this is supposed to do,so just return something type-compatible */  
  ParentClass<B> accept(Base base) { return this; }
}

ParentClass 是一个容器,子类为 Child1Child2

上面的

BaseParentClass 子类中包含的有效负载的基类。您需要负载的基类,因为容器类 (ParentClass) 是子类,并且您希望能够混合和匹配负载。

// Client.java

import java.util.HashMap;
import java.util.Map;

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

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

  void callAccept(String type,Base base) {
      map.get(type).accept(base);
  }
}

Java、Scala、Haskell 和其他语言使用 type theory,特别是 category theory 来精确定义允许的内容。实际上,在不迷失数学的情况下,上面的一般准则是使用泛型时的一些注意事项。

有关更多信息,请阅读 Joshua Bloch 撰写的“Effective Java”中有关通用容器的部分。我不相信他提到了范畴论,这很好。

如果您对“恰到好处”的类型理论感兴趣,请阅读 covariant types

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...