在特征

时间:2018-03-02 23:14:33

标签: scala oop traits

我创造了一个名为Animal的特质和两个类,Dog和Cat。狗和猫都有伴侣班,可以存储他们拥有的生命。我的猫对象有9个生命,我的Dog对象有1个生命。我想在一个名为isAlive的Animal trait中添加一个函数并在那里实现。 isAlive函数需要访问Animal拥有的实时数。如何访问伴侣类中的生命值?

我应该将生命值移到Class中并删除伴侣类吗?

这是我的代码。

特质

package Animal

trait Animal {

  def speak: String

  def getDeaths: Int

  def isAlive: Boolean = {
    getDeaths < 1 // I want to replace 1 with the number of lives from the Dog or Cat
  }
}

Cat Class and Companion Class

package Animal

class Cat(a: Int) extends Animal {
  private var age: Int = a
  private var deaths: Int = 0

  def this() = this(0)

  override def speak: String = {
    if (this.isAlive) {
      "Meow"
    }
    else {
      "..."
    }
  }

  // I want to do this in the trait
  // override def isAlive: Boolean = this.deaths <= Cat.lives

  def setAge(age: Int): Unit = this.age = age

  def getAge: Int = this.age

  def getDeaths: Int = this.deaths

  def die(): Unit = this.deaths += 1

}

object Cat {
  val lives: Int = 9
}

2 个答案:

答案 0 :(得分:2)

我在lives特征中包含Animal作为抽象方法,类似于getDeaths(顺便说一下,Scala并不遵循Java static {{ 3}})。

如果您熟悉Java,scala中的伴随对象类似于Java objects,这意味着class的类型解析在编译时发生,并且它是&#39;不可能像使用trait Animal { def speak: String def getDeaths: Int def lives: Int def isAlive: Boolean = { getDeaths < lives } } class Cat(a: Int) extends Animal { override val lives: Int = 9 private var age: Int = a private var deaths: Int = 0 def this() = this(0) /* ... */ } 的方法和字段一样使用多态。

以下是代码:

lives

或者,您可以在伴侣对象中定义lives常量,并在覆盖class Cat(a: Int) extends Animal { override val lives: Int = Cat.lives private var age: Int = a private var deaths: Int = 0 def this() = this(0) /* ... */ } object Cat { val lives = 9 } 方法时在具体类中引用它:

.publish().refCount()

答案 1 :(得分:2)

要在lives中访问trait,它必须是特征的一部分,正如@Alvean指出的那样,或者你必须要求扩展特征的类需要拥有它。

trait Animal { self: {val lives: Int} =>
  def isAlive: Boolean = getDeaths < lives
  . . .
}

class Cat(a: Int) extends Animal {
  val lives = Cat.lives  //required to be an Animal
  . . .
}