Рассмотрим абстрактный класс Element, это суперкласс для многих подклассов, таких как ArrayElement, каждый из которых имеет свои собственные вспомогательные методы, но с общим свойством param

Мне нужно вызвать вспомогательный метод printValue с объектом that. Метод check получает объект ArrayElement во время выполнения. Следовательно, во время выполнения, я надеюсь, не будет никаких проблем.

Но этот код не компилируется, объект that ищет метод printValue в абстрактном классе Element во время компиляции. Это заставляет меня объявить printValue в Element

Все вспомогательные методы в ArrayElement должны быть объявлены в супер абстрактном классе Element?

object ObjectTest {
    def main(args: Array[String]): Unit = {
        val x = new ArrayElement(999).check(new ArrayElement(333))
    }
}
abstract class Element {
    val param : Int
    def printValue : String  // commenting this line throws error below
}
class ArrayElement(override val param : Int) extends Element {
    def check(that: Element)  = {
       this.printValue
       println(that.param)
       println(that.printValue)  // throws error -- **value printValue is not a member of org.mytest.challenges.Element**
    }
    def printValue = "value:" + param
}
0
Praveen L 14 Мар 2018 в 14:53

2 ответа

Лучший ответ

Все вспомогательные методы в ArrayElement должны быть объявлены в супер абстрактном классе Element?

Да, они должны быть у вас, если ваш аргумент метода def check относится к типу суперкласса.

ИЛИ

Вы можете преобразовать входящий объект в целевой тип и вызвать нужный метод.

object ObjectTest {
  def main(args: Array[String]): Unit = {
     val x = new ArrayElement(999).check(new ArrayElement(333))
  }
}

abstract class Element {
    val param : Int
    // def printValue : String  // commenting this line throws error below
}
class ArrayElement(override val param : Int) extends Element {
   def check(that: Element)  = {
       this.printValue
       println(that.param)
       println(that.asInstanceOf[ArrayElement].printValue)
  }
  def printValue = "value:" + param
}

ИЛИ

Используйте метод def printValue как метод по умолчанию в родительском классе.

0
Puneeth Reddy V 14 Мар 2018 в 12:12

Если этот объект набирается как Element, то, если вы удалите printValue из Element, он не будет компилироваться. Кроме того, x также не является членом Element. Если метод проверки будет использоваться разными подклассами из Element, вы можете рассмотреть возможность переноса его в Element в качестве защищенного метода, он будет доступен из ArrayElement, поскольку он расширен.

object ObjectTest {
  def main(args: Array[String]): Unit = {
    val x = new ArrayElement(999).check(new ArrayElement(333))
  }
}

abstract class Element {
  val param : Int
  def printValue : String

  protected def check(that: Element)  = {
    this.printValue
    println(that.param)
    println(that.printValue)
  }
}

class ArrayElement(override val param : Int) extends Element {
  def printValue = "value:" + param
}

С другой стороны, если проверка будет просто методом ArrayElement, вам следует повторно ввести его как ArrayElement

0
jpedreira 14 Мар 2018 в 12:11