Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does extending a class in scala with constructor params add vals (fields) to the class?

Say I have:

class A(val foo: String)

class B(foo: String) extends A(foo)
class C(val foo: String) extends A(foo)
class D(override val foo: String) extends A(foo)
class E(bar: String) extends A(bar)

I'm interested in how much memory instances of each of these classes take up. Instances of class A will have a single member variable: foo.

How about classes B,C,D and E? How many member variables will they each have? I suspect E will have two (E.bar, A.foo), I expect D will have one (A.foo), but I wonder about B and C, might they have two? (B.foo, A.foo)?

like image 953
Alex Black Avatar asked Sep 10 '10 13:09

Alex Black


People also ask

What does Extends do in Scala?

extends: The extends keyword in Scala is used to inherit features of one class by another class. baseClass extends parentClass. This extends keyword is used to inherit class while creating a new one. With: the with keyword in Scala is used when we need to inherit more than one class by another class.

What is the difference between extends and with in Scala?

The first thing you inherit from can either be a trait or a class, using the extends keyword. You can define further inherited traits (and only traits) using the with keyword.

Can you extend case class Scala?

Extending a class in Scala user can design an inherited class. To extend a class in Scala we use extends keyword. there are two restrictions to extend a class in Scala : To override method in scala override keyword is required.

Can an object extend a class Scala?

Objects and classes are not completely decoupled. An object can extend another class, making its fields and methods available in a global instance.


2 Answers

All of the examples that compile (A, B, D, E) take exactly the same amount of storage space. In fact, even

class F(val bar: String) extends A(bar)

will have the data stored in one field--it just gets an extra accessor method for the same field. However, if you

class G(var bar: String) extends A(bar)

then a new field is constructed.

You can check all this by compiling your examples above and looking at the bytecode from javap -c Classname (note the putfield at 2: in the constructor of A):

public class Sizes$A extends java.lang.Object implements scala.ScalaObject{
public java.lang.String foo();
  Code:
   0:   aload_0
   1:   getfield    #11; //Field foo:Ljava/lang/String;
   4:   areturn

public Sizes$A(java.lang.String);
  Code:
   0:   aload_0
   1:   aload_1
   2:   putfield    #11; //Field foo:Ljava/lang/String;
   5:   aload_0
   6:   invokespecial   #18; //Method java/lang/Object."<init>":()V
   9:   return    
}

(And the lack of an extra putfield in F...)

public Sizes$F(java.lang.String);
  Code:
   0:   aload_0
   1:   aload_1
   2:   invokespecial   #15; //Method Sizes$A."<init>":(Ljava/lang/String;)V
   5:   return

(And the presence of one again in G...)

public Sizes$G(java.lang.String);
  Code:
   0:   aload_0
   1:   aload_1
   2:   putfield    #11; //Field bar:Ljava/lang/String;
   5:   aload_0
   6:   aload_1
   7:   invokespecial   #18; //Method Sizes$A."<init>":(Ljava/lang/String;)V
   10:  return
like image 167
Rex Kerr Avatar answered Sep 29 '22 18:09

Rex Kerr


You class C will require an override keyword on val foo to compile, rendering it identical to D. It will store its own copy of foo. You class B does not add storage unless someplace outside its constructor body there is a reference to foo. That would force a hidden field to be created to hold the constructor parameter. The constructor body is all the code within the class definition and outside any method body.

Addendum:

package storage

    class A(val foo: String)

    class B(             foo: String) extends A(foo)
//  class C(         val foo: String) extends A(foo)
    class D(override val foo: String) extends A(foo)
    class E(             bar: String) extends A(bar)
    class F(             bar: String) extends A(bar) { def barbar: String = bar }

I am perplexed by this:

% javap -private storage.F
Compiled from "Storage.scala"
public class storage.F extends storage.A implements scala.ScalaObject{
    public java.lang.String barbar();
    public storage.F(java.lang.String);
}

What is method barbar using to get its return value?

like image 43
Randall Schulz Avatar answered Sep 29 '22 16:09

Randall Schulz