In this series, we’ve already 
laid the foundations for Scala’s syntax as well as gotten a feel for how some of its 
object-oriented constructs
 work.  We haven’t really looked at any of these subjects in-depth 
however.  Most of our effort has been focused on high-level, flash bang 
overviews that just get you tasting your way into the language.  This 
post will go into greater depth regarding method syntax, touch a bit on 
scopes and attempt to cover how static members work in Scala.  We will 
also touch on a few gotchas due to “missing” imperative instructions.
Methods Galore
Scala isn’t called a “functional language” just because it’s 
Turing complete. 
 Scala has a very powerful and flexible syntax as it relates to methods,
 both declaration and invocation.  We’ve already seen some basic 
samples:
  | class Person {
  def firstName() = {
    var back:String = ...   // read from a database
    back
  }
}
 | 
 
Fairly straightforward.  But this doesn’t really give you the full 
picture.  In Java for example, you can create methods with different 
visibilities, modifiers and (oddly enough) return types.  Does Scala 
support all of this flexibility?
The answer is a qualified “yes”.  Scala does allow for different 
visibilities on not just methods, but any members.  For example:
  | class Person {
  private var name = "Daniel Spiewak"
  val ssn = 1234567890    // public constant field
 
  def firstName() = splitName()(0)   // public method
 
  private def splitName() = name.split(" ")    // private method
 
  protected def guessAge() = {
    import Math._
    round(random * 20)
  }
}
 | 
 
At the risk of going on a tangent, it’s worth pointing out the (seemingly) out of place 
import statement within the 
guessAge()
 method.  I mentioned in the first post that Scala’s import is far more 
powerful than Java’s.  One of its many charms is imparting to the power 
to import into a specific scope.  The 
import statement within 
guessAge() is much like a Java 
static import statement which only provides access to the 
Math members within the 
guessAge() method.  So we couldn’t just make a call to 
round() from within the 
splitName() method.  Rubyists can think of it much like the 
include
 statement without all of the hassle (it’s not actually including, it’s 
importing and so eliminating the need for fully-qualified names).
Scala access modifiers are also quite a bit more powerful than Java’s.  For example, 
protected
 by default limits access to only subclasses, unlike Java which also 
allows access to other classes in the same package.  More importantly 
though, Scala allows the developer to more explicitly specify the scope 
of the access modifier.  This is accomplished using the 
modifier[package] notation.  For example:
  | package com.codecommit.mypackage
 
class MyClass {
  private[mypackage] def myMethod = "test"
}
 | 
 
In this example, 
myMethod is access-restricted to both the enclosing class 
and the enclosing package.  Essentially, this is how the Java-style package private modifier can be emulated using Scala.  The 
protected
 modifier also allows such visibility qualifiers.  The one restriction 
here is that the package specified must be an enclosing package.  In the
 above example, specifying 
private[com.codecommit.mypackage] is perfectly valid, but 
private[scala.collection.immutable] would not be correct.
So with the exception of package-private, visibilities work about the
 same in Scala as they do in Java, both in syntax and function.  
Modifiers are really where things get interesting.  Scala has far fewer 
method modifiers than Java does, primarily because it doesn’t 
need so many.  For example, Scala supports the 
final modifier, but it doesn’t support 
abstract, native or
 synchronized:
  | abstract class Person {
  private var age = 0
 
  def firstName():String
  final def lastName() = "Spiewak"
 
  def incrementAge() = {
    synchronized {
      age += 1
    }
  }
 
  @native
  def hardDriveName():String
}
 | 
 
If we were in Java, we would write the above like this:
  | public abstract class Person {
    private int age = 0;
 
    public abstract String firstName();
 
    public final String lastName() {
        return "Spiewak";
    }
 
    public synchronized void incrementAge() {
        age += 1;
    }
 
    public native String hardDriveAge();
}
 | 
 
Yes, I know it’s more “Scala-esque” to use actors rather than 
synchronized(), but one step at a time.
You see how Scala keeps with its theme of making the common things 
concise?  Think about it, almost every method you declare is public, so 
why should you have to say so explicitly?  Likewise, it just makes sense
 that methods without a body should be implicitly abstract (unless 
they’re native).
One very important type-saving feature that you should see in the example above is that Scala doesn’t 
force
 you to declare the return type for your methods.  Once again the type 
inference mechanism can come into play and the return type will be 
inferred.  The exception to this is if the method can return at 
different points in the execution flow (so if it has an explicit return 
statement).  In this case, Scala forces you to declare the return type 
to ensure unambiguous behavior.
You should also notice that none of the Scala methods actually include a 
return statement.  This of course seems odd as judging by the Java translation, 
lastName() should return a 
String. 
 Well it turns out that Scala carries a useful shortcut for method 
returns: the last statement in an expression, be it a scope, a closure 
or a method becomes its return value.  This convention is also found in 
languages like Ruby and Haskell.  This example illustrates:
  | def name() = {
  val name = new StringBuilder("Daniel")
  name.append(" Spiewak");
  name.toString()
}
 
val s = name()
println(s)    // prints "Daniel Spiewak"
 | 
 
Again, in this example the return type of the method is inferred (as 
String).  We could just as easily have written the 
name() method as follows, it just would have been less concise.
  | def name():String = {
  val name = new StringBuilder("Daniel")
  name.append(" Spiewak");
  return name.toString()
}
 | 
 
This “returnless” form becomes extremely important when dealing with 
anonymous methods (closures).  Obviously you can’t return from a 
closure, you can only 
yield, however the principle is the 
same.  Since closures are often used to reduce code bulk and make 
certain algorithms more concise, it only makes sense that their return 
syntax would be as compact as possible:
  | val arr = Array(1, 2, 3, 4, 5)
val sum = arr.reduceLeft((a:Int, b:Int) => a + b)
 
println(sum)    // 15 
 | 
 
In this example we’re passing an anonymous method to the 
reduceLeft() method within 
Array.  This method just calls its parameter function repeatedly for each value pair, passing them as the 
a and 
b parameters.  Here’s the key part though: our anonymous method adds the two parameters and yields the result back to 
reduceLeft().  Again, no 
return statement (or actually, as a closure it would be 
yield).  Also, we don’t explicitly specify the return type for the closure, it is inferred from our last (and only) statement.
Method Overriding
A very important concept in object-oriented programming is method 
overriding, where a subclass redefines a method declared in a 
superclass.  Java’s syntax looks like this:
  | public class Fruit {
    public int getWorth() {
        return 5;
    }
}
 
public class Apple extends Fruit {
    @Override
    public int getWorth() {
        return 1;
    }
}
 | 
 
Technically, the 
@Override annotation is optional, but it’s 
still good practice to use it.  This gives you the compile-time 
assurance that you actually are overriding a method from a superclass.  
In principle, a method declared in a subclass overrides any method in 
the superclass declared with the exact same signature.  At first glance 
this seems great, less syntax right?  The problem is when you start 
dealing with APIs where you’re uncertain if you got the overriding 
method signature right.  You could just as easily overload the method 
rather than overriding it, leading to totally different functionality 
and sometimes hard-to-trace bugs.  This is where 
@Override comes in.
Scala actually has a bigger problem with method overriding than just 
signature verification: multiple inheritance.  Multiple inheritance is 
when one class inherits from more than one superclass.  C++ had this 
feature years ago, effectively demonstrating how 
horrible it can really be. 
 When Gosling laid out the initial spec for Java, multiple inheritance 
was one of the things specifically avoided.  This is good for 
simplicity, but it’s sometimes constraining on the power-end of life.  
Interfaces are great and all, but sometimes they just don’t cut it.
The key to avoiding ambiguities in the inheritance hierarchy is explicitly stating that a method 
must override a superclass method.  If that method has the same signature as a superclass method but doesn’t 
override it, a compile error is thrown.  Add to that significant ordering in the 
extends/with clauses, and you get a workable multiple-inheritance scheme.  But I’m getting ahead of myself…
Here’s the 
Fruit example, translated into Scala:
  | class Fruit {
  def worth() = 5
}
 
class Apple extends Fruit {
  override def worth() = 1
}
 | 
 
Notice that in Scala, 
override is actually a keyword.  It is
 a mandatory method modifier for any method with a signature which 
conflicts with another method in a superclass.  Thus overriding in Scala
 isn’t implicit (as in Java, Ruby, C++, etc), but explicitly declared.  
This little construct completely solves the problems associated with 
multiple inheritance in Scala.  We’ll get into 
traits and multiple inheritance in more detail in a future article.
Often times when you override a method, you need to call back to the 
superclass method.  A good example of this would be extending a Swing 
component:
  | class StrikeLabel(text:String) extends JLabel(text) {
  def this() = this("")
 
  override def paintComponent(g:Graphics):Unit = {
    super.paintComponent(g)
 
    g.setColor(Color.RED)
    g.drawLine(1, getHeight() / 2, getWidth() - 1, getHeight() / 2)
  }
}
 | 
 
This component is just a rack-standard 
JLabel with a red 
line drawn through its center.  Not a very useful component, but it 
demonstrates a pattern we see used a lot in Java: delegating to the 
superclass implementation.  We don’t want to actually implement all of 
the logic necessary to paint the text on the 
Graphics context with the appropriate font and such.  That work has already been done for us in 
JLabel.  Thus we ask 
JLabel to paint itself, then paint our 
StrikeLabel-specific logic on top.
As you see in the example, the syntax for making this superclass 
delegation is almost precisely the same as it is in Java.  Effectively, 
super is a special private value (much like 
this) which contains an internal instance of the superclass.  We can use the value just like 
super in Java to access methods and values directly on the superclass, bypassing our overriding.
That little bit of extra syntax in the 
extends clause is how you call to a superclass constructor.  In this case, we’re taking the 
text parameter passed to the default constructor of the 
StrikeLabel class and passing it on to the constructor in 
JLabel.  In Java you do the same thing like this:
  | public class StrikeLabel extends JLabel {
    public StrikeLabel(String text) {
        super(text);
    }
 
    public StrikeLabel() {
        this("");
    }
}
 | 
 
This may seem just a bit odd at first glance, but actually provides a
 nice syntactical way to ensure that the call to the super constructor 
is 
always the first statement in the constructor.  In Java, 
this is of course compile-checked, but there’s nothing intuitively 
obvious in the syntax 
preventing you from calling to the super 
constructor farther down in the implementation.  In Scala, calling the 
super constructor and calling a superclass method implementation are 
totally different operations, syntactically.  This leads to a more 
intuitive flow in understanding why one can be invoked arbitrarily and 
the other must be called prior to anything else.
Scala’s Sort-of Statics
Scala is a very interesting language in that it eschews many of the 
syntax constructs that developers from a Java background might find 
essential.  This ranges from little things like flexible constructor 
overloading, to more complex things like a complete 
lack of static member support.
So in Java, static members are just normal class members with a 
different modifier.  They are accessed outside of the context of a 
proper instance using the classname as a qualifier:
  | public class Utilities {
    public static final String APP_NAME = "Test App";
 
    public static void loadImages() {
        // ...
    }
 
    public static EntityManager createManager() {
        // ...
    }
}
 
System.out.println(Utilities.APP_NAME);
 
Utilities.loadImages();
EntityManager manager = Utilities.createManager();
 | 
 
Scala does support this type of syntax, but under the surface it is quite a bit different.  For one thing, you don’t use the 
static
 modifier.  Instead, you declare all of the “static” members within a 
special type of class which acts as an only-static container.  This type
 of class is called 
object.
  | object Utilities {
  val APP_NAME = "Test App"
 
  def loadImages() = {
    // ...
  }
 
  def createManager():EntityManager = {
    // ...
  }
}
 
println(Utilities.APP_NAME)
 
Utilities.loadImages()
val manager = Utilities.createManager()
 | 
 
The syntax to use these “statics” is the same, but things are quite a bit different in the implementation.  It turns out that 
object actually represents a singleton class.  
Utilities
 is in fact both the classname and the value name to access this 
singleton instance.  Nothing in the example above is static, it just 
seems like it is due to the way the syntax works.  If we port the above 
class directly to Java, this is what it might look like:
  | public class Utilities {
    private static Utilities instance;
 
    public final String APP_NAME = "Test App";
 
    private Utilities() {}
 
    public void loadImages() { 
        // ...
    }
 
    public EntityManager createManager() {
        // ...
    }
 
    public static synchronized Utilities getInstance() {
        if (instance == null) {
            instance = new Utilities();
        }
 
        return instance;
    }
}
 
// ...
 | 
 
So Scala provides a special syntax which basically gives us a 
singleton for free, without all of the crazy syntax involved in 
declaring it.  This is a really elegant solution to the problems with 
proper statics.  Since Scala doesn’t actually have static members, we no
 longer have to worry about mixing scopes, access qualifiers, etc.  It 
all just works nicely.
But what about mixing static and instance members?  Java allows us to do this quite easily since 
static is a qualifier, but Scala requires “static” members to be declared in a special singleton class.  In Java, we can do this:
  | public class Person {
    public String getName() {
        return "Daniel";
    }
 
    public static Person createPerson() {
        return new Person();
    }
}
 | 
 
The solution in Scala is to declare both an 
object and a 
class of the same name, placing the “static” members in the 
object and the instance members in the 
class.  To be honest, this seems extremely strange to me and is really the only downside to Scala’s singleton syntax:
  | object Person {
  def createPerson() = new Person()
}
 
class Person {
  def name() = "Daniel"
}
 | 
 
The syntax for using this 
object/class combination is 
exactly the same as it would be in Java had we mixed static and instance
 members.  The Scala compiler is able to distinguish between references 
to 
Person the 
object and references to 
Person the 
class.  For example, the compiler knows that we can’t create a new instance of an 
object, since it’s a singleton.  Therefore we must be referring to the 
class Person in the 
createPerson() method.  Likewise, if a call was made to 
Person.createPerson(), the compiler is more than capable of deducing that it must be a reference to the 
object Person
 as there is no way to access a method directly upon a class.  It’s all 
perfectly logical and consistent, it just strikes the eye funny when you
 look at it.
Conclusion
And so ends our two part, whirlwind tour of Scala’s object-oriented 
constructs, methods and statics.  There are of course trivialities along
 the way which we haven’t covered, but those are easy enough to learn 
now that you have the basics.  The more interesting syntax is still to 
come though.  For one thing, we’ve barely scratched the surface of all 
of the things that you can do with methods.  They don’t call it a 
“functional” language for nothing!  But in keeping with our goal to 
represent the imperative side of the Scala language, we’ll save that for
 later.
(codecommit) 
 
0 comments: on "Scala for Java Refugees Part 3: Methods and Statics"
Post a Comment