【问题标题】:scala superclass reference with sub class object not calling subclass method带有子类对象的scala超类引用不调用子类方法
【发布时间】:2018-08-22 22:44:38
【问题描述】:

考虑抽象类Element,这是许多子类的超类,例如ArrayElement,每个子类都有自己的帮助方法,但具有共同的param属性

我需要用that 对象调用辅助方法printValuecheck 方法在运行时接收 ArrayElement 对象。因此,在运行时,我希望不会有任何问题。

但是,这段代码没有编译,that 对象在编译时在抽象类Element 中寻找printValue 方法。它迫使我在Element 中声明printValue

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
}

【问题讨论】:

  • 将此行 println(that.x) 更改为 println(that.param) 希望这不是一个错误?
  • 对不起。那是一个错字。我编辑了我的问题。

标签: scala


【解决方案1】:

该对象被键入为 Element,然后如果您从 Element 中删除 printValue,它将无法编译。此外, 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
}

另一方面,如果 check 只是一个 ArrayElement 方法,则应将其重新键入为 ArrayElement

【讨论】:

  • '另一方面,如果 check 只是一个 ArrayElement 方法,您应该将其重新键入为 ArrayElement '——这就是我要找的...感谢 jpedreira 和 Puneeth reddy
  • @PraveenL 还记得,如果您从抽象类扩展,您必须实现其中定义的所有内容。
【解决方案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方法作为默认方法。

【讨论】:

  • 谢谢。这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 2016-01-22
  • 2017-05-13
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
相关资源
最近更新 更多