[英]Managing dependency graph via mixins in scala
我有一個需要2個特征的類,兩個特征都需要相同的特征。 我要如何在這種情況下添加它
class RandomTest extends AbstractTestCase {
"asdasd" should "asdsda" in {
val a = new Application with XYZAppName with Session with MetricsPublisher
a.a()
}
abstract class Application extends Session with MetricsPublisher {
println("Application")
def a() : Unit = { println("application.a")}
}
trait RequiredAppContext {
println("RequiredAppContext")
val appName : String
}
trait MetricsPublisher extends RequiredAppContext {
this:RequiredAppContext =>
println("MetricsPublisher")
}
trait Session extends RequiredAppContext{
this:RequiredAppContext =>
println("Session")
lazy val appNameoverload = func(appName)
def func(value:String ) {println("appNameoverload "+appName)}
}
// implmentations
trait XYZAppName extends RequiredAppContext {
println("XYZAppName")
override val appName = "xyz"
}
}
這是該程序的輸出:
[scalatest] RequiredAppContext
[scalatest] Session
[scalatest] MetricsPublisher
[scalatest] Application
[scalatest] XYZAppName
[scalatest] application.a
將XYZAppName初始化顯示在Session之前的最佳方法是什么?
Scala的線性化算法,管理特征圖初始化順序並解決菱形繼承問題,以聲明順序遍歷(非循環)繼承圖,滿足初始化父節點的要求,但忽略了已初始化的所有重復項。 這里的要點是要初始化某個類,您需要首先初始化其基類,以及擴展它的所有特征。 在extends
或new
extends
之后,Scala甚至不允許在任何位置指定基類-您只能使用with
來添加特征。 對於(匿名)類的a
基類是Application
:
a.type
-> Application
-> Session
-> RequiredAppContext
-> MetricsPublisher
-> RequiredAppContext // omitted
-> XYZAppName
-> RequiredAppContext // omitted
-> Session // omitted
-> RequiredAppContext // parent omitted
-> MetricsPublisher // omitted
-> RequiredAppContext // parent omitted
所以你唯一的選擇是修改你的繼承層次,轉向Application
到特質,並重新排序它XYZAppName
在定義a
:
trait Application extends Session with MetricsPublisher
...
val a = new XYZAppName with Application with Session with MetricsPublisher
// RequiredAppContext
// XYZAppName
// Session
// MetricsPublisher
// Application
但是,該解決方案無法涵蓋所有可能的情況-如果您的抽象類具有構造函數,則無法將其轉換為特征( 正在做的工作是在以后的Scala版本中允許特征參數,但距離完成還很遙遠)。 如果基類是在外部代碼中定義的,這也不是一個選擇。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.