简体   繁体   English

Scala特征:定义嵌套属性

[英]Scala traits: defining nested attributes

I'm very beginner Scala programmer who's coming from Java. 我是来自Java的初学者Scala程序员。 I'm trying to build an understanding of Scala's traits, as a superior alternative to Java's interfaces. 我试图加深对Scala特性的理解,作为Java接口的替代方案。 In this case, I want to create a trait which, when implemented, will require an object to have attributes, and one or more of those attributes will themselves be objects with required traits. 在这种情况下,我想创建一个特征,该特征在实现时将要求一个对象具有属性,而这些属性中的一个或多个本身就是具有必需特征的对象。 The following code demonstrates what I want, but it doesn't currently work. 以下代码演示了我想要的内容,但是当前不起作用。

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

So I want the Person trait to require the object to have an Address attribute, which itself has some required attributes. 因此,我希望Person特质要求该对象具有一个Address属性,该属性本身具有一些必需的属性。 The compiler doesn't like the above code defining the address in aPerson . 编译器不喜欢上面的代码在aPerson定义address

What's the right way to do this? 什么是正确的方法?

Bonus question : Let's say the Address trait is only used here. 奖励问题 :假设仅在此处使用“ Address特征。 Is there a way to define the Address trait anonymously inside the Person trait so it won't clutter the file? 有没有一种方法可以在Person特质内部匿名定义Address特质,以免文件混乱?

I think this is what you're trying to do. 我认为这就是您想要做的。

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

The Address trait can be made anonymous, but then traits like Person can't reference it because it has no named type. 可以将“ 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

You can override a def with an object . 您可以使用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"
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM