【问题标题】:How scala compiler invoking abstract method from super class?scala编译器如何从超类调用抽象方法?
【发布时间】:2019-02-24 15:38:58
【问题描述】:

我是 Scala 世界的新手,对 OOPS 概念有点困惑。这是我的代码 sn-p。

abstract class Element {
  def contents: Array[String]
  val lenth = contents.size
  val maxLength = contents.map(_.size).max
}
class ArrayElement(var contents: Array[String]) extends Element

据我了解,Scala 编译器会为我们生成 contents , contents_= 方法。因此我们可以避免在基类中定义 def contents 抽象方法。我的理解正确吗?如果是的话

val names = Array("welcome", "apple", "Test")
    val names1 = Array("apple", "Test")
    var t = new ArrayElement(names);
    println(t.contents.mkString(",")) //Op : welcome,apple,Test
    t.contents = names1 // because of var

#1 println(t.contents.mkString(",")) // op : apple,Test #2 println(t.lenth) // 这里我得到 3(名字的长度)。但我期待 2 。为什么 ? #3 println(t.maxLength) // 同名参考这里。为什么?

'#1 给出更新的名单。但是#2 和#3 给出了旧名称引用。为什么 ?

【问题讨论】:

    标签: scala


    【解决方案1】:

    如果你反编译 Element 类你会发现类似这样的东西:

    public abstract class Element {
      private final int lenth =  // call contents()
      private final int maxLength = // call contents()
    
      public abstract String[] contents();
    
      public int lenth() {
        return this.lenth;
      }
    
      public int maxLength() {
        return this.maxLength;
      }
    }
    

    所以 lenthma​​xLength 字段在对象创建阶段初始化一次并且永远不会改变。

    当你反编译 ArrayElement 类时,会出现这样的情况:

    public class ArrayElemen extends Element {
    
      private String[] contents;
    
      @Override
      public String[] contents() {
          return this.contents;
      }
    
      //...
    }
    

    因此,当您调用 t.contents 时,它将被转换为 t.contents() 返回您更改后的值。

    【讨论】:

      【解决方案2】:

      lenthmaxLength 都是对象 ArrayElement 的状态,并且在初始化期间只更新一次 ArrayElement 班级。更改 contents 后,lenth 和 maxLength 都不会更新为 names1

      如果您正在寻找更新的lenthmaxLength

      abstract class Element {
        def contents: Array[String]
      
        //  val lenth = contents.size
        //  val maxLength = contents.map(_.size).max
      
        def lenth = contents.size
        def maxLength = contents.map(_.size).max
      
      }
      

      当然,您可以通过不同的方式实现这一点。

      【讨论】:

      • 你也可以应用“统一访问原则”,让解决方案更加优雅。
      • 我会推荐两本书。 Scala 编程第 2 版。另一本书名为 Programming in Scala(由 Scala 创作者编写)..
      • 这两本书是同一本书。只有版本不同
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2020-02-15
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多