Learn Hadoop
Learn Hadoop

Reputation: 3050

How scala compiler invoking abstract method from super class?

I am new to Scala world and bit confused with OOPS concept . 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. hence we can avoid to define def contents abstract method in base class. 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) . but i am expecting 2 . Why ? #3 println(t.maxLength) // same names reference here . Why ?

'#1 is giving updated names list. But #2 and #3 is giving old name references. Why ?

Upvotes: 2

Views: 50

Answers (2)

Balaji Reddy
Balaji Reddy

Reputation: 5700

Both lenth and maxLength are states of the object ArrayElement and it gets updated just once during the initialization of ArrayElement class. After you chnaged contents, both lenth and maxLength are not updated with names1.

If you are looking for updated lenth and maxLength.

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.

Upvotes: 2

Bogdan Vakulenko
Bogdan Vakulenko

Reputation: 3390

If you decompile Element class you will find something similar to this:

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.

And when you decompile ArrayElement class there will be something like this:

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.

Upvotes: 3

Related Questions