Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Using companion object's parent's protected methods

Tags:

scala

I have a set of classes that manage db storage in a class hierarchy as outlined below, and would like for the case class to be able to access the protected methods in the companion object's parent class:

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(...)
}

Only problem is that the call to User.update in User.changeEmail is illegal since User (class) is not in the inheritance chain from 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

Is there a (convenient) way to allow for this type of calling?

Right now I have to either move the changeEmail-type functions into the singleton, which makes the calling code rather verbose, or duplicate the method signatures.

like image 491
Jxtps Avatar asked May 28 '26 01:05

Jxtps


1 Answers

I just realized that a possible solution is to switch the "is-a" to a "has-a" relationship between User and TableBase, like so:

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(...)
}

I wanted to be able to customize some aspects of TableBase inside User, but that's actually still possible and quite easy by doing:

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

Actually, that's a much better solution than what I originally had and avoids naming conflicts on the methods (i.e. there's reason to have a public "insert" on User and it's nice to not have it result in partly protected overloading).

like image 99
Jxtps Avatar answered May 30 '26 15:05

Jxtps



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!