【问题标题】:type parameters generics in interfaces and concrete classes接口和具体类中的类型参数泛型
【发布时间】:2014-04-03 06:28:44
【问题描述】:

我正在创建类似的东西,并对 java 中泛型的使用感到震惊。

想法:Producer产生T类型的东西,consumers包含命令对象,命令对象拥有不同的中介 .中介者持有 Subject 类型的对象并更新 T

类型的值

注意:我这样做是为了了解泛型在泛型类型的继承以及泛型类型接口和具体类中类型参数定义的组合方面是如何工作的,所以请不要担心设计。

接口定义:

组成:

  1. IObserver

  2. ISubject 包含类型 T 和 IObserver 的对象。

  3. IMediator 拥有 ISubject 类型和 T 类型的对象

  4. ICommand 拥有 IMediator 类型和 T 类型的对象

  5. IProducerConsumer 持有 T 和 ICommand 类型的对象。

对应的接口有一些具体的对象。 我定义了这样的接口:

public interface IObserver<T>
public interface ISubject<T,O extends IObserver<T>>

酷到现在。但现在问题开始了。

public interface IMediator<T,S extends ISubject<T,O>, O extends IObserver<T>>

编译器强迫我这样做。我的意思是O extends IObserver&lt;T&gt; 如上所述。所以,我推断我不能像下面这样定义

public interface IMediator<T,S extends ISubject<T,O extends IObserver<T>> >

我的结论是:不能像上面那样扩展内部类型参数定义。 所以,终于满意了 公共接口IMediator&lt;T,S extends ISubject&lt;T,O&gt;, O extends IObserver&lt;T&gt;&gt; 现在混乱开始在 ICommand public interface ICommand &lt;T,M extends IMediator&lt;T, ?, ?&gt;&gt;,

我现在很震惊编译器不接受我的许多可能性,即使我做出上述推断也是如此。我是说

public interface ICommand <T,M extends IMediator<T, S, o>, S extends ISubject<T, IObserver<T>>,O extends IObserver<T>>

不工作。 我不想使用通配符,我想告诉编译器一些更具体的东西。

我的问题是:

  1. 我的推断是否与 ICommand 定义中的一样正确。

  2. 如何解读上述案例研究。

  3. 假设我想插入 T 并且必须能够获取和放置,那么最好的定义是什么。

  4. 接口和实现类中类型参数定义的规则和关系是什么。

请解释一下?

【问题讨论】:

  • public interface ICommand&lt;T, M extends IMediator&lt;T, S, O&gt;, S extends ISubject&lt;T, O&gt;, O extends IObserver&lt;T&gt;&gt; 有效。但实际上:通常不需要如此大量的类型参数。由于这是非常虚构的,我现在不能告诉你如何减少类型参数。也许你可以再解释一下要求(更容易理解)?
  • 好的。请定义如下接口:生产者生产 T 类型的东西,消费者包含命令对象,命令对象将值更新到相应的命令对象,命令对象持有不同的中介。中介者持有 Subject 类型的对象并更新 T 类型的值
  • 好的,我看到您编辑了帖子的结构(现在更具可读性)。但我仍然没有得到全貌。您能否描述一下您的每个界面的角色和意图?此外,您在小创意描述中提到了产品和消费者。但后来你讲了一个接口 IProducerConsumer。这怎么搭配?我真的很愿意帮助您理解这个(虚构的)场景,但我仍在努力满足要求。
  • 好吧,忘记上面的。有 4 个 A、B、C、D 类和相应的接口。让我们考虑像 IA,IB,IC 和 ID 组合这样的接口如下 IA 持有类型 T 的对象,IB 持有类型 T 的对象并组合 A 对象及其子类型,然后 C 持有类型 T 和 B 的对象及其子类型和相同对于 D。如何将所有这些作为接口和具体类的泛型类型。避免无限制地使用通配符。感谢您的谈话时间。
  • 对我来说,不知道这些课程是关于什么的,这太令人困惑了。发展关乎行为,而不仅仅是结构。抱歉,我想我帮不了你。

标签: java generics inheritance type-parameter


【解决方案1】:

带有绑定参数的泛型(无通配符)

  • 我的推断是否与 ICommand 定义中的一样正确?

    否。 两个原因
    1. 您在传递给Mediator 时写了一个小“o”。 (我猜这只是一个打字错误。)
    2. 您将IObserver&lt;T&gt; 而不是O 传递给ISubject,这肯定会导致参数绑定不匹配。

正确版本:

interface ICommand<T, M extends IMediator<T, S, O>, S extends ISubject<T, O>, O extends IObserver<T>>

  • 如何解读上述案例研究?

    1. 首先需要了解的是,您有 一个 未知类型 T 和 五个 接口。
    2. 因此,您将拥有总共 六个 必须逐步包含在接口声明中的具体类型。 (您明确要求不要打扰设计的基本原理。)
    3. 如果您以正确的顺序编写它们,它会变得更易于管理。

接口声明:

interface IObserver<T>

interface ISubject<T, O extends IObserver<T>>

interface IMediator<T, O extends IObserver<T>, S extends ISubject<T,O>>

interface ICommand<T, O extends IObserver<T>, S extends ISubject<T, O>, 
                   M extends IMediator<T, O, S>>

interface IProducerConsumer<T, O extends IObserver<T>, S extends ISubject<T, O>,
                   M extends IMediator<T, O, S>, C extends ICommand<T, O, S, M>>

  • 假设我要插入 T 并且必须能够获取和放置,那么最好的定义是什么?

    1. 如果您想获取和放置类型为 T 的对象,您可能需要的是 一堆接口,它们需要只有一个参数 T。泛型将强制所有都兼容,因为 T 将在任何地方被相同的类型替换。
    2. 您当前的系统过于僵化。在实际场景中,您永远不会有这么多这些接口的实现(除非您在 java 中重新实现 facebook),因此您会有很多可能的实现组合并且您希望确保兼容性。
    3. 泛型通过应用良好的限制来强制类型安全。但是你不应该仅仅因为你可以设置它们就设置限制。您正在失去代码的灵活性可读性可维护性
    4. 您应该只在需要时添加边界。它们不应该以任何方式影响设计在接口之间的合同确定之前。

可能足够的方式:

interface IObserver<T>

interface ISubject<T>

interface IMediator<T>

interface ICommand<T>

interface IProducerConsumer<T>

  • 接口和实现类中类型参数定义的规则和关系是什么?

    1. 我能想到的接口中的类型参数和实现类之间的唯一关系是实现类必须提供一个类型来替换泛型类型参数。
    2. 在某些情况下,该类型又可以是泛型类型,在这种情况下,提供具体类型的责任将转交给使用类引用或扩展该类的另一个类的代码。 它甚至可能是递归的!
    3. 规则不是用该语言编写的,而是您在此机制上应用所有规则当您绑定任何类型参数时。因此,只要您提供符合所有规则的类型,您就可以开始了。
    4. 更多规则意味着更强大灵活性/可读性较差。明智地进行交易也是如此。

两个简单的案例:

// General way
private class ProductObserver implements IObserver<Product> { }

private ProductObserver productObserver;

// Aspect oriented way
private class LoggerObserver<T> implements IObserver<T> { }

private LoggerObserver<Product> loggerObserver;

  • 最后,如果您有任何疑问,我建议您阅读(综合)Java Generics FAQ Angelika Langer
  • 如果您继续这样尝试,您还不如最终发明一种设计模式。当你这样做时,不要忘记与我们分享:D

希望这会有所帮助。
祝你好运。

【讨论】:

  • 您好 Tanmay 解释得很好,并说到了我真正想了解的内容。我不能停止感谢你。我知道我的意图不是应用内聚/耦合/深度注入等原则的简洁设计。即使看起来像。在这里,我的意图是在组合和继承的上下文中,绑定不匹配、隐藏变量是如何工作的。一旦我到达这里,我们无法在书籍或在线资料中获得的是在接口泛型类型中使用类型参数定义,并且在定义具体类时更具体。安吉丽娜兰格真的很有见地。谢谢。
  • 很高兴知道它有帮助。
猜你喜欢
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-25
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
相关资源
最近更新 更多