Reputation: 1287
I have written a Scala class Sheltie
to understand how scopes work in Scala. I wrote an equivalent Java Sheltie class just as a cross-reference. This is where I ran into trouble.
In the body of the Scala Sheltie
class, there is a method call to the method called bark
and a println
statement just after the bark
call. An equivalent method call bark()
can be placed in the equivalent Java class inside another method, but outside of any method, it understandably complains of Duplicate method bark()
.
I understand how Java code works, so this behavior (in Java) is not surprising. What perplexes is why Scala behaves the way it does.
What I hope to solve is: Why does Scala allow "calls" in the class body and why it allows one to create another val definition in the if block, when Java does not.
Foo.scala
class Sheltie {
val barkNum = 10
def bark() {
//local barkNum of "bark" method
val barkNum = 20
if(true){
//local "barkNum" of if-block
val barkNum = 30 //why does Scala not complain of a duplicate local variable, when Java does in the equivalent program Sheltie.java
println("Inside if block: No of times Riley barked is " + barkNum)
}
println("Outside if block: No of times Riley barked is " + barkNum)
}
bark //Why does this work, when you can't do this in Java
println("Outside bark: No of times Riley barked is " + barkNum)
}
Upvotes: 1
Views: 188
Reputation: 159754
When you say Scala allows calls in the class body, the body is actually the constructor, so this is equivalent to having:
public Sheltie()
{
bark();
System.out.println("Outside bark: No of times Riley barked is " + barkNum);
}
in Java.
Upvotes: 6
Reputation: 297175
Just complementing about barkNum
. Scala has simple rules about scoping and declarations. Briefly:
Upvotes: 2
Reputation: 12852
In Scala, statements (excluding declarations) "in the class body" are executed as part of the default constructor. You will be able to observe this when you instantiate an object of class Sheltie
. Additional constructors are called auxiliary constructors in Scala.
class Test(a: Int) {
println("a = " + a)
}
new Test(1) /* Prints a = 1 */
Regarding variable shadowing, there isn't really a right or wrong thing to do. Scala allows you to shadow variables, other languages don't. My guess is that it is allowed because programming in a functional style often leads to lots of local variables existing in a very limited scope, e.g., from closure declarations.
Upvotes: 5