gpt4 book ai didi

swing - Scala Wrapper 类通过扩展 Component 和 SequentialContainer.Wrapper 特征,我对特征有正确的理解吗?

转载 作者:行者123 更新时间:2023-12-01 03:51:51 27 4
gpt4 key购买 nike

以下代码取自这篇文章:How to create Scala swing wrapper classes with SuperMixin?

import scala.swing._
import javax.swing.JPopupMenu

class PopupMenu extends Component with SequentialContainer.Wrapper {
override lazy val peer: JPopupMenu = new JPopupMenu with SuperMixin

def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y)
}

我一直在尝试制作自定义包装器,所以需要理解这一点,这很简单,但因为
我才刚刚开始熟悉 Scala,所以我对特性有点不确定。所以我一直听到的是,特征就像多重继承,你可以混合和匹配它们?

我绘制了一个图表,表示 PopupMenu 在整个继承结构中的位置。只是为了澄清一些事情:

1)它似乎从 Component 覆盖了惰性 val peer:JComponent 并且还从 SequentialContainer.Wrapper 获取了 contents 属性? (紫色文字)对吗?

2) Sequential.Wrapper 也有一个抽象的 def 对等体:JComponent.. 但这不是被覆盖的那个,所以这里根本不使用它吗?

3) 令人困惑的是 Component 和 Sequential.Wrapper 有一些相同的属性:它们都有 def publish 和 def subscribe (红色文本).. 但是 popupMenu 将使用的是 Component 类的订阅/发布?

4) 为什么我们不能用 Component 来编写 PopupMenu extends SequentialContainer.Wrapper 呢?

希望这不是一次太多的问题。非常感谢您的帮助,我是 Scala 的初学者..
diagram representing the inheritance/trait relationship leading up to popupMenu

最佳答案

我将使用您的问题数量来回答:

  • 正确
  • 正确的。最高特征是 UIElement它定义了一个抽象成员 def peer: java.awt.Component .然后你有 Container仅添加抽象成员 def contents: Seq[Component]能够读取子组件。 Container.WrapperContainer 的具体实现假设(抽象地)Java 对等体是 javax.swing.JComponent .请注意,在 Java 自己的层次结构中,javax.swing.JComponentjava.awt.Component 的子类型,所以不存在冲突。子类型可以细化其成员的类型(“协方差”)。 SequentialContainer精炼 Containercontents是一个可变缓冲区(而不是只读序列)。因此,它的实现 SequentialContainer.Wrapper混入 Container.Wrapper但替换 contents通过标准 Scala 缓冲区。从来没有具体的peer给了,还。为方便起见,Component确实实现了该成员,但正如您所见,最后一个类 PopupMenu覆盖 peer .由于类型系统的工作方式,所有参与的特征都可以访问 peer , 但仅限 PopupMenu “知道”该类型已被细化为 javax.swing.JPopupMenu .例如 SequentialContainer.Wrapper只知道有一个javax.swing.JComponent ,所以它可以使用peer的这部分API。
  • Publisher trait 由 UIElement 引入, 所以你会发现它来自 UIElement 的所有类型. 在层次结构中多次出现相同的特征并没有错。在最后一个类中,只有一个 Publisher 的实例。 ,不存在它的多个“版本”。 即使Publisher没有在根中定义,但在例如 Component 中独立定义和 SequentialContainer.Wrapper ,您只会在最终类中获得一个实例。
  • 这是个简单的。在 Scala 中,您只能扩展一个类,但可以混合任意数量的特征。 Component是一个类,而其他所有东西都是特征。它是 class A extends <trait-or-class> with <trait> with <trait> ... .


  • 综上所述,所有 GUI 元素都继承自 trait UIElementjava.awt.Component 支持.具有子元素的元素使用特征 Container ,并且所有允许您按特定顺序添加和删除元素的普通面板类型元素都使用 SequentialContainer . (并非所有面板都有顺序,例如 BorderPanel 没有)。这些是抽象接口(interface),要获得所有必要的实现,你有 .Wrapper类型。最后要得到一个可用的类,你有 Component扩展 UIElement并要求对等方是 javax.swing.JComponent ,因此它可以实现所有标准功能。

    当你实现一个新的包装器时,你通常使用 Component并细化 peer键入以便您可以访问该对等点的特定功能(例如 showJPopupMenu 方法)。

    关于swing - Scala Wrapper 类通过扩展 Component 和 SequentialContainer.Wrapper 特征,我对特征有正确的理解吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21750459/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com