【问题标题】:Scala traits: defining nested attributesScala 特征:定义嵌套属性
【发布时间】:2018-01-12 20:59:31
【问题描述】:

我是来自 Java 的非常初学者的 Scala 程序员。我正在尝试建立对 Scala 特性的理解,作为 Java 接口的更好替代品。在这种情况下,我想创建一个特征,它在实现时将要求对象具有属性,并且这些属性中的一个或多个本身将是具有所需特征的对象。以下代码演示了我想要的,但它目前不起作用。

trait Person{
  def name: String
  def age: Int
  def address extends Address

}

trait Address{
  def streetName: String
  def streetNumber: Int
  def city: String
}

object aPerson extends Person {
  override val name = "John"
  override age = 25
  override address = object { //this doesn't work
     def streetName = "Main St."
     def streetNumber = 120
     def city = "Sometown"
  }
}

所以我希望 Person 特征要求对象具有 Address 属性,该属性本身具有一些必需的属性。编译器不喜欢上面在aPerson 中定义address 的代码。

这样做的正确方法是什么?

额外问题:假设Address trait 仅在此处使用。有没有办法在 Person 特征内匿名定义 Address 特征,以免文件混乱?

【问题讨论】:

    标签: scala traits


    【解决方案1】:

    我认为这就是你想要做的。

    trait Person{
      val name: String
      val age: Int
      val address: Address
    }
    
    trait Address{
      val streetName: String
      val streetNumber: Int
      val city: String
    }
    
    object aPerson extends Person {
      val name = "John"
      val age = 25
      val address: Address = new Address { //this now works
        val streetName = "Main St."
        val streetNumber = 120
        val city = "Sometown"
      }
    }
    

    Address 特征可以匿名,但是像 Person 这样的特征不能引用它,因为它没有命名类型。

    trait Person{
      val name: String
      val age: Int
    //val address: ?type?
    }
    
    object aPerson extends Person {
      val name = "John"
      val age = 25
      val address = new { //this also works
        val streetName = "Main St."
        val streetNumber = 120
        val city = "Sometown"
      }
    }
    
    aPerson.address.city  //res0: String = Sometown
    

    【讨论】:

    • 关于使其匿名的第二个建议不起作用,因为没有命名类型,其他代码无法进行类型检查,这完全有道理。所以我想我只是不会匿名声明它。但第一段代码完美运行!
    【解决方案2】:

    您可以用object 覆盖def

    trait Person {
      def name: String
      def age: Int
      def address: Address
    }
    
    object aPerson extends Person {
      val name = "John"
      val age = 25
      object address extends Address {
        val streetName = "Main St."
        val streetNumber = 120
        val city = "Sometown"
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 1970-01-01
      • 2015-08-10
      • 1970-01-01
      • 2022-01-01
      • 2019-08-02
      相关资源
      最近更新 更多