Scala - 使用子上下文绑定方法覆盖特征方法

Ora*_*rar 1 scala traits context-bound

对于

sealed trait User {...}
sealed trait Trader extends User {...}

trait AuthObject

trait AuthUserObject {
  def authorize[U <: User](u: U): Boolean
}

trait AuthTraderObject extends AuthUserObject {
  def authorize[T <: Trader](t: T): Boolean
}

object HasPaidTax extends AuthTraderObject {
  def authorize[T <: Trader](t: T): Boolean = t.hasPaidTax
}
Run Code Online (Sandbox Code Playgroud)

这不构建.错误:

错误:(15,7)覆盖方法在特征[U <:users.User](u:U)布尔值的特征AuthUserObject中授权; 方法授权具有不兼容的类型def authorize [T <:Trader](t:T):Boolean ^

我需要限制AuthTraderObject到Trader,因为只有交易者缴纳税款的用户.请问,这种覆盖怎么可能?

Ale*_*nov 5

首先,您应该了解错误的原因:自HasPaidTax扩展以来AuthUserObject,您可以将此类型归因于它:

val auth: AuthUserObject = HasPaidTax
Run Code Online (Sandbox Code Playgroud)

但对于任何auth: AuthUserObject和user: User,你可以打电话auth.authorize(user).因此,当重写方法时,您无法缩小参数类型或键入边界.

对于解决方案,您可以使用pamu的答案或只是将类型参数移动到类型(对于这种情况应该是等效的):

trait AuthUserObject[U <: User] {
    def authorize(u: U): Boolean
}

trait AuthTraderObject[T <: Trader] extends AuthUserObject[T] {
    def authorize(t: T): Boolean
}

object HasPaidTax extends AuthTraderObject[Trader] {
    def authorize(t: Trader): Boolean = t.hasPaidTax
}
Run Code Online (Sandbox Code Playgroud)