在定义子类函数时遇到问题

时间:2012-11-28 20:25:42

标签: scala

我有以下抽象类:

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方法时,我收到以下错误: 对象创建不可能,因为方法insertNew在类的Accessor类中(模型:  package.Model)未定义选项[package.Model](注意  package.Model与package.AccountModel不匹配

这是我的实施课程

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

    ...do stuff
}

我做错了什么?

感谢

2 个答案:

答案 0 :(得分: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: Abstract types vs generics

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

答案 1 :(得分:0)

我认为你缩小了对象中insertNew的范围,因此它不再符合它的要求。您的insertNew方法只能接受大于M2mModel不低于此类的类。

这应该有效:

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

而且:

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

想象一下,如果你将这个对象传递给只知道M2mModel而不是AccountModel的东西。函数insertNew只接受AccountModel,因此另一个M2mModel不起作用。