user504909
user504909

Reputation: 9549

How to provide ambiguous reference in scala inherit trait?

I have trait, this trait is already defined in framework and can not change:

trait GenericProfile {
def firstName: Option[String]
def lastName: Option[String]
def fullName: Option[String]
def email: Option[String]
def avatarUrl: Option[String]
}

I want a class inherit it as:

class BasicProfile(
providerId: String,
userId: String,
firstName: Option[String],
lastName: Option[String],
fullName: Option[String],
email: Option[String],
avatarUrl: Option[String]
) extends GenericProfile{
def providerId=this.providerId  //ambiguous reference will be here
...
}

But if I do not re-define the unimplemented method, there is still error since the value in BasicProfile is regarded as private and do not regard it as already implemented.

I understand that it can simply write as override, but I have another class in practice:

case class IdProfile(id:String,
providerId: String,
userId: String,
firstName: Option[String],
lastName: Option[String],
fullName: Option[String],
email: Option[String],
avatarUrl: Option[String])extends BasicProfile(providerId,userId,firstName,lastName,  fullName,email, avatarUrl){

}

I do not want the IdProfile override the methods from its parents class BasicProfile, just inherit would be OK.

Upvotes: 0

Views: 188

Answers (2)

Timo
Timo

Reputation: 433

Since BasicProfile has to make sure all that the defined methods of the trait are implemented (since you don't want to use an abstract class), I'd recommend using a case class for the BasicProfile.

You can extend the BasicProfile with an IdProfile class (not case class) and override the specific methods you are interesed in (or leave them be). If I'm not mistaken that's what your trying to accomplish?

trait GenericProfile {
  def firstName: Option[String]
  def lastName: Option[String]
  def fullName: Option[String]
  def email: Option[String]
  def avatarUrl: Option[String]
}

 

case class BasicProfile(
  providerId: String,
  userId: String,
  var firstName: Option[String],
  var lastName: Option[String],
  var fullName: Option[String],
  var email: Option[String],
  var avatarUrl: Option[String]
) extends GenericProfile{
}

 

class IdProfile(id:String,
  providerId: String,
  userId: String,
  firstName: Option[String],
  lastName: Option[String],
  fullName: Option[String],
  email: Option[String],
  avatarUrl: Option[String])extends BasicProfile(providerId,userId,firstName,lastName,  fullName,email, avatarUrl){
}

If you are trying to stay away from case class I'd recommend taking a look at this Question: Simple Scala getter/setter override

Hope this helps.

Upvotes: 1

Dan Getz
Dan Getz

Reputation: 9152

To define a readable field in the argument list to a class's constructor, you can use val:

class BasicProfile(
  val providerId: String,
  val firstName: Option[String],
  ...
) extends GenericProfile {
  ...
}

When you do not put val (or alternatively var for a mutable field) on the constructor argument, a field is generally not created.

If you define your class as a case class, then constructor arguments without modifiers are treated as if they have val in front of them, and fields are created for them:

case class BasicProfile(
  providerId: String,
  ...
) extends GenericProfile {
  ...
}

Upvotes: 0

Related Questions