Scala traits:定义嵌套属性

Scala traits: defining nested attributes

我是来自 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 特征仅在此处使用。有没有办法在 Person 特征中匿名定义 Address 特征,这样它就不会弄乱文件?

我想这就是你想要做的。

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

您可以用 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"
  }
}