从特征中定义的方法中的伴随类访问常量

问题描述 投票:0回答:2

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

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

这是我的代码。

特质

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和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
}
scala oop traits
2个回答
2
投票

我将lives作为Animal特征中的抽象方法,类似于getDeaths(顺便说一句,Scala不遵循Java的naming conventions for getters and setters)。

如果您熟悉Java,scala中的伴随对象类似于Java的static,这意味着objects的类型解析发生在编译时,并且不可能像使用class的方法和字段一样使用多态。

这是代码:

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
}

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
  . . .
}
© www.soinside.com 2019 - 2024. All rights reserved.