Scala特征:定义嵌套属性

时间:2018-01-12 20:59:31

标签: scala traits

我是初学Scala程序员,来自Java。我试图建立对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属性,该属性本身具有一些必需属性。编译器不喜欢在address中定义aPerson的上述代码。

正确的方法是什么?

加分问题:让我们说Address特征仅在此处使用。有没有办法在Address特征内匿名定义Person特征,这样就不会使文件混乱?

2 个答案:

答案 0 :(得分:2)

我认为这是你正在尝试做的事情。

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

答案 1 :(得分:1)

您可以使用def覆盖object

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