简体   繁体   English

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

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

I am new to Scala world and bit confused with OOPS concept . 我是Scala世界的新手,对OOPS概念有些困惑。 Here is my code snippet. 这是我的代码段。

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

From my understanding Scala compiler will generate contents , contents_= method for us. 根据我的理解,Scala编译器将为我们生成contents,contents_ =方法。 hence we can avoid to define def contents abstract method in base class. 因此我们可以避免在基类中定义def内容抽象方法。 is it my understanding correct ? 我的理解正确吗? if it yes 如果是的话

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) // here i am getting 3 (length of names) . #1 println(t.contents.mkString(“,”))// op:苹果,测试#2 println(t.lenth)// //我得到3(名称的长度)。 but i am expecting 2 . 但我期望2。 Why ? 为什么呢 #3 println(t.maxLength) // same names reference here . #3 println(t.maxLength)//此处引用相同的名称。 Why ? 为什么呢

'#1 is giving updated names list. '#1正在提供更新的姓名列表。 But #2 and #3 is giving old name references. 但是#2和#3提供了旧的名称引用。 Why ? 为什么呢

If you decompile Element class you will find something similar to this: 如果您反编译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;
  }
}

So lenth and maxLength fields are initialized once during object creation stage and never change. 因此, lenthmaxLength字段在对象创建阶段初始化一次,并且永远不会更改。

And when you decompile ArrayElement class there will be something like this: 当您反编译ArrayElement类时,将出现以下内容:

public class ArrayElemen extends Element {

  private String[] contents;

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

  //...
}

So when you call t.contents it will be translated to t.contents() returning your changed value. 因此,当您调用t.contents时 ,它将转换为t.contents()并返回更改后的值。

Both lenth and maxLength are states of the object ArrayElement and it gets updated just once during the initialization of ArrayElement class. lenthmaxLength都是对象ArrayElement状态,并且在ArrayElement类的初始化期间仅更新一次。 After you chnaged contents , both lenth and maxLength are not updated with names1 . 更改contents ,lenth和maxLength都不会使用names1更新。

If you are looking for updated lenth and maxLength . 如果您正在寻找更新的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

}

Of course , you can achieve this in different ways. 当然,您可以通过不同的方式实现这一目标。

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

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