繁体   English   中英

Scala编译器如何从超类调用抽象方法?

[英]How scala compiler invoking abstract method from super class?

我是Scala世界的新手,对OOPS概念有些困惑。 这是我的代码段。

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内容抽象方法。 我的理解正确吗? 如果是的话

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:苹果,测试#2 println(t.lenth)// //我得到3(名称的长度)。 但我期望2。 为什么呢 #3 println(t.maxLength)//此处引用相同的名称。 为什么呢

'#1正在提供更新的姓名列表。 但是#2和#3提供了旧的名称引用。 为什么呢

如果您反编译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;
  }
}

因此, lenthmaxLength字段在对象创建阶段初始化一次,并且永远不会更改。

当您反编译ArrayElement类时,将出现以下内容:

public class ArrayElemen extends Element {

  private String[] contents;

  @Override
  public String[] contents() {
      return this.contents;
  }

  //...
}

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

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

}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM