0

我有以下抽象类:

abstract class Accessor {

  def get(rowkey:String): Option[M2mModel]
  def insertNew(model: M2mModel): Option[M2mModel]


}

abstract class Model(active:Int) {

  @BeanProperty
  var ttl = None

}

我的实现类是:

object AccountModel {
  val COL_USERNAME = "username"
  val COL_EMAIL = "email"
  val COL_PASSWORD = "password"
  val COL_DOMAIN = "domain"
  val COL_ACTIVE = "active"
  val COL_ROLE = "role"
  val COL_ACLID = "aclid"

  val definedFields = List(COL_USERNAME, COL_EMAIL, COL_PASSWORD, COL_DOMAIN, 
    COL_ACTIVE, COL_ROLE, COL_ACLID)

  def apply(rowkey:String, email:String, password:String) = new AccountModel(rowkey, email, password) 

}


case class AccountModel(rowkey: String, email:String, password: Option[String], 
  username: Option[String], domain: Option[String],
  role: Option[String], active: Int, aclid: Option[String]) extends M2mModel(active) {

  def this(rowkey:String, email:String, password:String) = this(rowkey, email, Some(password),
      None, None, None, 1, None)

}

当我创建 Accessor 类并实现 insertNew 方法时,出现以下错误:无法创建对象,因为类型为 (model: package.Model)Option[package.Model] 的 Accessor 类中的方法 insertNew 未定义(请注意 package.型号与 package.AccountModel 不匹配)

这是我的实现类

object AccountAccess extends Accessor {
 def insertNew(model: AccountModel): Option[AccountModel] = {

    ...do stuff
}

我究竟做错了什么?

谢谢

4

2 回答 2

1

这里的问题是该insertNew方法需要 M2mModel 类型的东西,并且只能通过解析为相同签名的方法来实现。

在 Scala 中,我们可以通过两种方式解决这个问题。

类型参数化

我们可以将 Accessor 视为一个泛型类,它与扩展 M2mModel 的 T 类型的东西一起工作:

abstract class Accessor[T <: M2mModel] {
    def get(rowkey:String): Option[T]
    def insertNew(model: T): Option[T]
}

AccountAccess并像这样扩展:

object AccountAccess extends Accessor[AccountModel] {
    def insertNew(model: AccountModel): Option[AccountModel] = {
        ???
    }

    def get(rowkey: String) = ???
}

抽象类型成员

我们可以认为Accessor是一个在其实现中处理T扩展的抽象类型的对象的类M2mModel

abstract class Accessor {

    type T <: M2mModel

    def get(rowkey:String): Option[T]
    def insertNew(model: T): Option[T]

}

在这种情况下,扩展类AccountAccess应该指定这个类型T应该是什么:

object AccountAccess extends Accessor {

    type T = AccountModel

    def get(rowkey: String) = ???

    def insertNew(model: AccountModel) = ???
}

就个人而言,我确实相信第二种选择是更好的方法。

你可以在这里找到一个非常有趣的讨论:

Scala:抽象类型与泛型

请务必阅读它,因为它将帮助您在将来以非常优雅和模块化的方式解决此类问题。

于 2012-11-28T22:33:47.733 回答
0

我认为您正在缩小对象中 insertNew 的范围,因此它不再满足它的要求。您的 insertNew 方法只能接受大于M2mModel不能更低的类。

这应该有效:

 def insertNew(model: M2mModel): Option[M2mModel]

还有这个:

 def insertNew(model: Any): Option[Any]

想象一下,如果您将此对象传递给只知道 M2mModel 而不知道 AccountModel 的东西。函数 insertNew 只需要 AccountModel,因此另一个 M2mModel 将无法工作。

于 2012-11-28T20:41:13.670 回答