Swing 通过扩展组件并使用SequentialContainer.Wrapper trait扩展Scala包装器类,我对traits有正确的理解吗?
以下代码取自此帖子: 我一直在尝试制作定制包装,所以需要理解这一点,这很简单,但从那时起 我才刚刚开始熟悉Scala,所以我对它的特点有点不确定。所以我一直听到的是,特质就像多重遗传一样,你可以混合搭配它们 我画了一个图表,表示PopupMenu在整个继承结构中的位置。我只想澄清几件事: 1) 它似乎覆盖了组件中的lazy val peer:JComponent,还从SequentialContainer.Wrapper中获取contents属性?(紫色文本)是这样吗 2) 包装器还有一个抽象的def对等体:JComponent。。但这不是被覆盖的,所以这里根本不使用它 3) 令人困惑的是组件和Sequential.Wrapper有一些相同的属性:它们都有def publish和def subscribe(红色文本)。。但是弹出菜单将使用的是来自组件类的subscribe/publish 4) 为什么我们不能用组件来编写PopupMenu扩展SequentialContainer.Wrapper呢 希望不要一次问太多问题。非常感谢您的帮助,我是Scala的初学者。。Swing 通过扩展组件并使用SequentialContainer.Wrapper trait扩展Scala包装器类,我对traits有正确的理解吗?,swing,scala,inheritance,mixins,traits,Swing,Scala,Inheritance,Mixins,Traits,以下代码取自此帖子: 我一直在尝试制作定制包装,所以需要理解这一点,这很简单,但从那时起 我才刚刚开始熟悉Scala,所以我对它的特点有点不确定。所以我一直听到的是,特质就像多重遗传一样,你可以混合搭配它们 我画了一个图表,表示PopupMenu在整个继承结构中的位置。我只想澄清几件事: 1) 它似乎覆盖了组件中的lazy val peer:JComponent,还从SequentialContainer.Wrapper中获取contents属性?(紫色文本)是这样吗 2) 包装器还有一个抽象的
我将使用您的问题编号来回答:
UIElement
,它定义了一个抽象成员def peer:java.awt.Component
。然后您就有了Container
,它只添加了抽象成员def contents:Seq[Component]
,以便能够读取子组件Container.Wrapper
是Container
的一个具体实现,它(抽象地)假设Java对等体是javax.swing.JComponent
。请注意,在Java自己的层次结构中,javax.swing.JComponent
是Java.awt.Component
的子类型,因此没有冲突。子类型可以细化其成员的类型(“协方差”)SequentialContainer
通过说明内容
是一个可变缓冲区(而不是只读序列)来细化容器
。因此,它的实现SequentialContainer.Wrapper
混合在Container.Wrapper
中,但用标准的Scala缓冲区替换内容。在任何时候都没有给出一个具体的peer
。为方便起见,组件确实实现了该成员,但是正如您所看到的,最后一个类弹出菜单
覆盖了对等对象
。由于类型系统的工作方式,所有参与的trait都可以访问peer
,但只有PopupMenu
“知道”类型已被细化为javax.swing.jpopmenu
。例如,SequentialContainer.Wrapper
只知道存在一个javax.swing.JComponent
,因此它可以使用对等API的这一部分
Publisher
特性是由UIElement
引入的,因此您可以在从UIElement
派生的所有类型中找到它在层次结构中多次出现相同的特征没有错。在最后一个类中,只有Publisher
的一个实例,不存在它的多个“版本”。即使Publisher
未在根目录下定义,但独立于例如组件
和SequentialContainer.Wrapper中,在最后一个类中只能得到一个实例
A类扩展为…
总之,所有GUI元素都继承自trait
UIElement
,它由java.awt.Component
备份。具有子元素的元素使用traitContainer
,所有允许您按特定顺序添加和删除元素的普通面板类型元素使用SequentialContainer
。(并非所有面板都有顺序,例如BorderPanel
没有顺序)。这些是抽象接口,要获得所有必要的实现,您需要.Wrapper
类型。最后,为了获得一个可用的类,您有组件
,它扩展了UIElement
,并要求对等方是javax.swing.JComponent
,因此它可以实现所有标准功能
实现新包装器时,通常使用组件
并优化对等体
类型,以便可以访问该对等体的特定功能(例如jpopmenu
的show
方法)
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)
}