简体   繁体   English

在客户端代码中处理多个具有类型的类

[英]Handling multiple Classes with Types in client code

Suppose if I have the following classes假设我有以下课程

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

Now if I have a client code where I want to have both instances of child1 and child2 mapped to a string in a map (and) also make use of accept method, seems its impossible and I get it why.现在,如果我有一个客户端代码,我希望将 child1 和 child2 的实例都映射到 map 中的字符串(并且)也使用接受方法,这似乎是不可能的,我明白了为什么。 Is there a Better work around?有更好的解决方法吗?

My client code looks like,我的客户代码看起来像,

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
    } 

} 

#Update 1 Adding the return type in the example as I missed when I typed the question from mobile. #Update 1 在示例中添加返回类型,因为当我从移动设备键入问题时我错过了。

"Better" depends on what you want to achieve. “更好”取决于您想要实现的目标。 As I understand your question, you just want to be able to compile the code and understand it.据我了解您的问题,您只想能够编译代码并理解它。 Many variations are possible, and "best" would depend on the business problem you are addressing.许多变化是可能的,“最佳”将取决于您正在解决的业务问题。

Absent a business problem that the code might address, here is code that compiles without error.没有代码可能解决的业务问题,这里的代码编译没有错误。 I fixed several errors in your code:我修复了您代码中的几个错误:

// 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 , a container, is subclassed as Child1 and Child2 . ParentClass是一个容器,是Child1Child2的子类。

Base above is a base class for the payload contained within ParentClass subclasses.上面的Base是包含在ParentClass子类中的有效负载的基础 class。 You need a base class for the payload because the container class ( ParentClass ) is subclassed, and you want to be able to mix and match payloads.您需要一个基本的 class 作为有效负载,因为容器 class ( 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 and other languages use type theory , specifically category theory to define precisely what is allowable. Java、Scala、Haskell 和其他语言使用类型理论,特别是类别理论来精确定义允许的内容。 Practically speaking, and without getting lost in math, the general guidelines above are a few of the considerations for working with generics.实际上,在不迷失数学的情况下,上述一般准则是使用 generics 的一些注意事项。

For more information, please read the section on generic containers in “Effective Java” by Joshua Bloch.有关更多信息,请阅读 Joshua Bloch 的“Effective Java”中关于通用容器的部分。 I don't believe he mentions category theory, which is good.我不相信他提到范畴论,这很好。

If you are interested in "just enough" type theory, read about covariant types .如果您对“刚刚好”的类型理论感兴趣,请阅读协变类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM