type Currency <: AbstractCurrency
我无法理解这是什么意思。
type Currency <: AbstractCurrency
我无法理解这是什么意思。
这意味着定义了一个抽象类型成员(在某个上下文中,例如trait或class),因此该上下文的具体实现必须定义该类型。然而,有个限制,即该类型(Currency
)必须实际上是AbstractCurrency
的子类型。这样,抽象上下文就可以使用Currency
,知道它理解AbstractCurrency
的每个操作。
trait AbstractCurrency {
def disappearInGreece(): Unit
}
abstract class Economy {
type Currency <: AbstractCurrency
def curr: Currency
// can call disappear... because `Currency`
// is an `AbstractCurrency`
def shake(): Unit = curr.disappearInGreece()
}
尝试定义没有限制的Currency
:
trait RadioactiveBeef
class NiceTry(val curr: RadioactiveBeef) extends Economy {
type Currency = RadioactiveBeef
}
失败。有约束条件:
trait Euro extends AbstractCurrency
class Angela(val curr: Euro) extends Economy {
type Currency = Euro
}
它的意思是“必须是子类型”,“必须符合”,“必须扩展”。 大多数情况下,它会出现在泛型参数的限定中,例如:
class Home[P <: Person]
每个住所都适合某种类型的人,Home[Person]
接受任何人,可能会有 Home[Student]
、Home[Elderly]
,但没有 Home[Planet]
。
type Currency <: AbstractCurrency
在出现它的 class
/trait
中引入了一个抽象的类型成员 Currency
。后代必须选择一个类型以使它们变得具体化。<: AbstractCurrencies 强制它们选择 AbstractCurrency
的子类型(包括允许的 AbstractCurrency
)。
抽象类型成员与类型参数非常接近,就像抽象值成员与构造函数参数一样接近。
如果你有 class A(val x: X){...}
,你可以使用 new A(myX)
来实例化第一个。如果你有 class A{val x: X; ...}
,你可以使用 new A{val x = myX }
来实例化。
如果你有 class Market[Currency <: AbstractCurrency]
,你可以用 Market[SomeCurrencyType]
来实例化该类型。如果你有 Market{type Currency <: AbstractCurrency}
,你可以使用 Market{type Currency = SomeCurrencyType}
来实例化。不过,Market
是一个有效的类型。这意味着你不知道这个市场使用什么类型的货币(这可能会限制你如何使用它)。
与类型参数相比,使用抽象类型成员可能具有优势,特别是当类型参数未出现在类型的公共接口中时,如果 Market
没有 Currency
作为函数参数或结果(在这个例子中不太可能)。那么客户端就不需要编写 Market[SomeCurrencyType]
,而是可以直接使用 Market
。当然,创建市场时必须知道 CurrencyType
,但然后它可以简单地传递为 Market
。
我希望添加一些内容,描述<:符号的可用性优势。
假设您为API定义了以下类:
case class myApiClass[param <: BaseParameter](requestBody: String, parameter: param)
您有一个名为BaseParameter的特性
trait BaseParameter
接下来,您将拥有以下参数:
case object Parameter1 extends BaseParameter
case object Parameter2 extends BaseParameter
case object Parameter3
现在,每当您创建myApiClass实例时,都必须将一个对象作为参数“parameter”传递,该对象的类/本身实现BaseParameter(例如Parameter1和Parameter2)。具体来说,这是一个断言,并且如果您传递Parameter3,则不起作用。