Scala:使用伴侣对象的父级受保护方法

时间:2012-09-06 00:42:39

标签: scala

我有一组在类层次结构中管理数据库存储的类,如下所述,并且希望case类能够访问companion对象的父类中的受保护方法:

class TableBase[T] { 
  protected def insert(...):T {...}
  protected def update(...) {...}
  // Other "raw" CRUD-methods that I don't want the 
  // world to have access to
}

object User extends TableBase[User] { 
}

case class User(id:Int, email:String) { 
  // But here it would be really useful to access the "raw" CRUD methods:
  def changeEmail(newEmail:String) = User.update(...)
}

唯一的问题是User.changeEmail中对User.update的调用是非法的,因为User(class)不在TableBase的继承链中:

method update in class TableBase cannot be accessed in object models.User 
Access to protected method update not permitted because enclosing class 
class User in package models is not a subclass of class TableBase in package 
models where target is defined

是否有(方便)方式允许此类呼叫?

现在我必须将changeEmail类型的函数移动到单例中,这使得调用代码相当冗长,或者复制方法签名。

2 个答案:

答案 0 :(得分:1)

我刚刚意识到可能的解决方案是切换" is-a"到了" has-a" User和TableBase之间的关系,如下所示:

class TableBase[T] { 
  def insert(...):T {...}
  def update(...) {...}
}

object User { 
  private val db = new TableBase[User]
}

case class User(id:Int, email:String) { 
  def changeEmail(newEmail:String) = User.db.update(...)
}

我希望能够在User中自定义TableBase的某些方面,但实际上这仍然是可行的并且非常容易:

object User { 
  private val db = new TableBase[User] { 
    // Override stuff here
  }
}

实际上,这比我原来的解决方案要好得多,并且避免了对方法的命名冲突(即有理由公开"插入"用户及其#" 39;很高兴没有它导致部分保护的重载)。

答案 1 :(得分:0)

您可以将接口作为特征提供CrudOps [T],从中派生另一个 protected 特征TableBase [T]并提供实现,并从TableBase [T]派生单例对象。这样,TableBase在编译单元外部不可见,但客户端可以安全地使用CrudOps [T]。