【问题标题】:Scala - Overriding trait method using a sub context bound methodScala - 使用子上下文绑定方法覆盖特征方法
【发布时间】:2017-01-25 14:25:07
【问题描述】:

对于

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
}

这不成立。错误:

错误:(15, 7) 在 [U <: users.user u trait authuserobject def authorize trader t boolean>

我需要将AuthTraderObject 限制为Trader 用户,因为只有交易者纳税。请问,这个覆盖怎么可能?

【问题讨论】:

    标签: scala traits context-bound


    【解决方案1】:

    首先,你应该明白错误的原因:由于HasPaidTax扩展了AuthUserObject,你可以将这种类型归因于它:

    val auth: AuthUserObject = HasPaidTax
    

    但对于任何auth: AuthUserObjectuser: 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
    }
    

    【讨论】:

      【解决方案2】:

      用户类型,然后在必要时覆盖类型

      trait User
      
      trait Trader extends User
      
      
      trait AuthUserObject {
        type U <: User
        def authorize(u: U): Boolean
      }
      
      trait AuthTraderObject extends AuthUserObject {
        override type U <: Trader
        override def authorize(u: U): Boolean
      }
      

      【讨论】:

      • 使用type U &lt;: User 将其表示为AuthUserObject.this.U。在明确的情况下可以正常工作。但不适用于抽象类的抽象方法或特征上限类型有界trait Authorizer[U &lt;: User]
      猜你喜欢
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多