Получение ошибки в intellij, ссылающейся на метод scala, который я на самом деле не использую в классе, который я использовал - PullRequest
0 голосов
/ 30 октября 2019

Я играю и изучаю немного скала и столкнулся со странной ошибкой, которую я не понимаю и не могу найти способ исправить.

Вот код, который я пытаюсьвыполнить:

object Classes {
def main(args: Array[String]): Unit = {

    val rover = new Animal()
    rover.setName("Rover")
    rover.setSound("Woof")
    printf("%s says %s\n", rover.getName(), rover.getSound())

    val cat = new Animal("Tiddles", "Meow")
    println(s"${cat.getName()} with ID ${cat.id} says ${cat.getSound()}")

    println(cat.toString())

    val onions = new Dog("Onions", "Woof", "Grrrrrr....")
    onions.setName("Onions")
    println(onions.toString())

    val fang = new Wolf("Fang")
    fang.moveSpeed = 41.56387
    println(fang.move)
}

class Animal (var name: String, var sound: String) {

    this.setName(name)

    val id: Int = Animal.newIdNum

    def getName : String = name
    def getSound: String = sound

    def setName(name : String): Unit = {
        if (!(name.matches(".*\\d+.*")))
            this.name = name
        else
            this.name = "No Name"
    }

    def setSound(sound: String): Unit = {
        this.sound = sound
    }

    def this(name: String) {
        this("No Name", "No Sound")
        this.setName(name)
    }

    def this() {
        this("No Name", "No Name")
    }

    override def toString: String = {
        return "%s with ID %d says %s".format(this.name, this.id, this.sound)
    }
}

object Animal {
    private var idNumber = 0
    private def newIdNum = {
        idNumber += 1;
        idNumber
    }
}

class Dog(name: String, sound: String, growl: String) extends Animal(name, sound) {

    def this(name: String, sound: String) {
        this("No Name", sound, "No Growl")
        this.setName(name)
    }

    def this(name: String) {
        this("No Name", "No Sound", "No Growl")
        this.setName(name)
    }

    def this() {
        this("No Name", "No Sound", "No Growl")
    }

    override def toString: String = {
        return "%s with ID %d says %s or %s\n".format(this.name, this.id, this.sound, this.growl)
    }
}

abstract class Mammal(val name: String) {
    // Just declare variables and only define method signatures
    var moveSpeed : Double
    def move : String
}

class Wolf(name: String) extends Mammal(name) {
    override var moveSpeed: Double = 35.0
    override def move: String = "%s runs at %.2f mph\n".format(this.name, this.moveSpeed)
}

}

и вот ошибка, которую я получаю:

Error:(7, 37) not enough arguments for method apply: (index: Int)Char in class StringOps.
Unspecified value parameter index.
printf("%s says %s", rover.getName(), rover.getSound())

Error:(7, 55) not enough arguments for method apply: (index: Int)Char in class StringOps.
Unspecified value parameter index.
printf("%s says %s", rover.getName(), rover.getSound())

Error:(10, 26) not enough arguments for method apply: (index: Int)Char in class StringOps.
Unspecified value parameter index.
println(s"${cat.getName()} with ID ${cat.id} says ${cat.getSound()}")

Error:(10, 67) not enough arguments for method apply: (index: Int)Char in class StringOps.
Unspecified value parameter index.
println(s"${cat.getName()} with ID ${cat.id} says ${cat.getSound()}")

Я не использовал метод apply из класса StringOps, поэтому у меня нетидея, почему это жалуется, что я не указал параметр;index.

Само собой разумеется, если я закомментирую 2 строки, упомянутые в ошибках, он запустится.

Любые предложения по поводу того, почему компилятор ищет этот метод применения.

1 Ответ

1 голос
/ 30 октября 2019

Лучше использовать объект-компаньон для создания разных вариантов такого класса. (Я пропустил логику id и toString, так как в принципе это нормально).

class Animal protected (initalName: String, initialSound: String) {
  private def checkedName(name: String): String =
    if (name.matches(".*\\d+.*")) {
      "No Name"
    } else {
      name
    }

  protected var _name = checkedName(initalName)
  def name: String = _name
  def setName(name: String): Unit =
    _name = checkedName(name)

  var sound = initialSound
}

object Animal {
  def apply(name: String, sound: String): Animal = new Animal(name, sound)
  def apply(name: String): Animal = new Animal(name, "No Sound")
  def apply(): Animal = new Animal("NoName", "No Sound")
}

class Dog protected (name: String, sound: String, val growl: String) extends Animal(name, sound)

object Dog {
  def apply(name: String, sound: String, growl: String): Dog = new Dog(name, sound, growl)
  def apply(name: String, sound: String): Dog = new Dog(name, sound, "No Growl")
  def apply(name: String): Dog = new Dog(name, "No Sound", "No Growl")
  def apply(): Dog = new Dog("No Name", "No Sound", "No Growl")
}

Обычно также отбрасывают get из методов доступа, чтобы они выглядели как свойства объекта.

Также обратите внимание, что Scala предназначен для функционального программирования, поэтому типично делать этот тип неизменяемым. Это означает, что метод setName станет методом withName и вернет новый (неизменный) экземпляр класса. Такой подход кажется более неуклюжим с самого начала, но приносит выгоды по мере усложнения логики.

...