【问题标题】:How to provide ambiguous reference in scala inherit trait?如何在 scala 继承特征中提供模棱两可的参考?
【发布时间】:2014-07-31 18:16:38
【问题描述】:

我有 trait,这个 trait 已经在框架中定义并且不能改变:

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

我想要一个类继承它:

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

但是如果我不重新定义未实现的方法,仍然有错误,因为BasicProfile中的值被认为是私有的,不认为它已经实现了。

我知道它可以简单地写成覆盖,但我在实践中还有另一个类:

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){

}

我不希望 IdProfile 覆盖其父类 BasicProfile 中的方法,只需继承即可。

【问题讨论】:

    标签: scala inheritance


    【解决方案1】:

    由于 BasicProfile 必须确保 trait 定义的所有方法都已实现(因为您不想使用抽象类),我建议对 BasicProfile 使用 case class

    您可以使用 IdProfile class(不是 case class)扩展 BasicProfile,并覆盖您感兴趣的特定方法(或保留它们)。如果我没记错的话,这就是你想要完成的?

    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){
    }
    

    如果您想远离case class,我建议您看看这个问题:Simple Scala getter/setter override

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      要在类的构造函数的参数列表中定义一个可读字段,可以使用val

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

      当您不将val(或者var 用于可变字段)放在构造函数参数上时,通常不会创建字段。

      如果您将类定义为案例类,则不带修饰符的构造函数参数将被视为前面有val,并为它们创建字段:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-29
        • 1970-01-01
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多