【问题标题】:Java "events" - nothing more than Interfaces. Why pretend it is Events when it is just a normal Interface and classes that implements that interface?Java“事件”——只不过是接口。当它只是一个普通的接口和实现该接口的类时,为什么还要假装它是事件呢?
【发布时间】:2010-01-07 04:29:36
【问题描述】:

我主要使用 .NET C# 进行开发,我喜欢 C# 中的事件。

我现在正在做一些 Android 的东西,因此必须处理 Java。在将一些代码从 C# 移植到 Java 时,我遇到了事件的问题; Java 没有任何与 C# 事件相对应的东西。

因此,在阅读 Java 如何处理“事件”时,我唯一能得出的结论是它没有。 Java 中没有“事件”之类的东西。相反,他们使用普通的接口和实现这些接口的类。

在 Java 中: 首先,您必须先创建接口 然后,所有想要监听“事件”的类都必须实现该接口。 然后,触发“事件”的类必须保留所有侦听器的列表(某种数组) 然后,触发“事件”的类必须有一个方法,以便侦听器可以将自己添加到数组中

当触发类决定“触发事件”时,它必须遍历侦听器的数组,调用方法。

这只是简单的接口用法,而不是我的世界中的事件。

我错了吗?

【问题讨论】:

  • “呸呸呸,这另一种语言没有我最喜欢的语言的内置功能”。

标签: c# java android


【解决方案1】:

没有人“假装”。 Java 概念早在设计 C# 之前就已实现。 C# 中的事件在内部实际上是相同的。尽管它们对程序员来说更容易使用。也就是说,C# 事件变量维护一个事件订阅方法列表,订阅者可以从该列表中添加和删除方法引用。该事件为所属类提供了一种触发事件的方法。

您对“事件”的定义是什么?这是一种旨在将一个类系统与另一个类系统分离的设计模式。在任何一种情况下(C# 或 Java),其他类都可以订阅接收事件通知,只是订阅和消息触发器的实现有所不同。

在 C# 中,您必须定义事件方法签名(委托)。这就是接口的作用。

C# 确实添加了 Java 所没有的功能,即您可以传递对方法的引用(delegate,尽管我现在知道这可能在 Java 7 中可用,至少在 JVM 级别)。由于这在 Java 中不存在,因此必须有另一种方法来提供必须是对象的事件(观察者设计模式)接收器,并且定义它的最佳方法是通过接口 - 是的,您可以使用抽象类,但是这将严重限制收件人类型。

【讨论】:

  • 当然,它们可能是“幕后”的同一件事,但这有点不相关。我只是反对他们将其称为事件的事实,而实际上它与正常的接口使用没有什么不同。为什么不直接说“JAVA 没有事件,而是使用接口”...
  • @Ted - 您对“事件”的定义似乎是“.NET 已经实现的”。好吧,还有其他定义。事件只是发生某事的通知 - 该通知如何发生取决于编程语言或该语言使用的通用设计模式(例如在 API 中)。您可以忽略这一点,也可以在您需要工作的环境中尽力而为。
  • 当然,我必须充分利用 JAVA 提供的功能。那不是问题 =) 我只是说当 JAVA 中没有特定的构造时开始谈论事件是一种误导。就是这样=)
  • @Ted - 我认为说 Java 没有事件但 .net 有事件是一种误导,而你真正的意思是 Java 没有事件关键字但 .net 有。仅仅因为不同的语言有不同的实现标准模式的方式(Java 使用接口,.net 使用 event 关键字)并不意味着它们不能支持这些模式。
【解决方案2】:

它确实只是普通的接口,尽管有一个命名和实现“约定”——XXXListener 和匿名内部类。我认为这很好并且工作得很好——核心语言不必因为“事件”的概念而变得臃肿(也许这个词有点太苛刻了——我不想引发一场激烈的战争)。

AFAIK Android 从 Swing 中汲取了这种模式的灵感。

请注意,大多数语言没有像 Singleton、Observer 这样的模式的语言结构......如果模式可以轻松实现,则没有必要 - 如果它稍微复杂一点,它可以由库实现,工具包或框架。

【讨论】:

    【解决方案3】:

    JavaBeans 是关于“约定优于配置”的。 :-P 事件只需使用名为addXXXListenerremoveXXXListenergetXXXListeners 的方法即可生成,其中涉及的类型派生自侦听器接口。

    以同样的方式,只需使用名为 getXXXsetXXX 的方法(对于只读或只写属性都可以省略)来创建属性。

    程序如何定位事件和属性?通过使用java.beans.Introspector,可以很好地使用这些命名约定。

    有时,最简单的就是最好的。 :-D

    【讨论】:

    • 不是真的。对于开发人员来说,这听起来需要做更多的工作。怎么这么简单?编译器可能更简单,但谁在乎呢?
    • 开发人员的工作量如何?对于初学者,您不必为方法添加大量样板注释/属性。
    【解决方案4】:

    为了澄清,Android SDK 实现和公开事件概念的方式与 Java 语言不同。不同的工具包(即 Swing、SWT)有自己的做事方式。

    【讨论】:

      【解决方案5】:

      在 Java 中,事件代表用户和应用程序之间发生的所有活动。 Java 的抽象窗口工具包 (AWT) 使用事件将这些操作传达给程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-18
        • 1970-01-01
        • 1970-01-01
        • 2015-02-18
        • 1970-01-01
        • 2016-02-07
        • 1970-01-01
        • 2012-01-18
        相关资源
        最近更新 更多