Version 1.7
Copyright © 2009 Lars Vogel
22.11.2009
| Revision History | ||
|---|---|---|
| Revision 0.1 | 14.02.2009 | Lars Vogel |
| First version - Draft | ||
| Revision 0.2 | 14.06.2009 | Lars Vogel |
| Added Eclipse installation, first scala example | ||
| Revision 0.3 | 15.06.2009 | Lars Vogel |
| Variables in Scala | ||
| Revision 0.4 | 23.08.2009 | Lars Vogel |
| Bug report for first scala project | ||
| Revision 0.5 | 24.08.2009 | Lars Vogel |
| Added JDT Weaving | ||
| Revision 0.6 | 25.08.2009 | Lars Vogel |
| Hello Scala World working | ||
| Revision 0.7 | 21.09.2009 | Lars Vogel |
| Functions | ||
| Revision 0.8 | 22.09.2009 | Lars Vogel |
| Loops | ||
| Revision 0.9 | 09.10.2009 | Lars Vogel |
| Collections | ||
| Revision 1.0 | 10.10.2009 | Lars Vogel |
| Added clean tip | ||
| Revision 1.1 | 22.10.2009 | Lars Vogel |
| Added case clases | ||
| Revision 1.2 | 04.11.2009 | Lars Vogel |
| Added recursive functions | ||
| Revision 1.3 | 08.11.2009 | Lars Vogel |
| Class and constructors, objects | ||
| Revision 1.4 | 12.11.2009 | Lars Vogel |
| override | ||
| Revision 1.5 | 14.11.2009 | Lars Vogel |
| Method names, traits | ||
| Revision 1.6 | 21.11.2009 | Lars Vogel |
| uniform access principle | ||
| Revision 1.7 | 22.11.2009 | Lars Vogel |
| switch | ||
Table of Contents
Scala stands for scalable language which indicates that Scala is suitable for small scripting tasks as well as large enterprise applications. The creator of Scala is Martin Odersky.
Scala is a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way. Scale compiles to Java bytecode and therefore runs on the JVM.
Scala is a hybrid language, it is a object-orientated progrmaming languate as well a functional programming language.
Skala has objects and classes. Objects are singletons and are defined via the keyword "object". Classes are defined via the keyword "class".
Scala does not support primitive types, everything is Scala is an object, e.g. the number 1 is an object and has methods.
Methods can use special signs, e.g. +, -, ->, =>. For example the sign "+" is a method defined for the Object integer. As Scala allows you to avoid the dot and the braces if a method has only one parameter you still can write 1+2 but this really means 1.+(2) and is a method call to the method "+" to the instance 1 of object integer.
Scala tries to be very concise, for example semicolons at the end of a line are optional. Scala follows the uniform access principle , which describes that the access to method invocation and field selection should be the same (this principle was taken from the programming language Eiffel).
You can use this update site http://www.scala-lang.org/scala-eclipse-plugin to install the Scala Plugin for Eclipse. See Eclipse Update Manager for using the update manager.
You need to activate the JDT Weaving. Select Windows -> Preferences -> JDT Weaving and press "Enable". A restart of Eclipse is required.

To create a Scala application you define an object (which is the equivalent of an Singleton in Java ).
Create a new Scale project "de.vogella.scala.first" via File -> New -> Project ->Scala Wizards -> Scala Projects


Press finish.
Right click on the "src" folder and select New - Package and create the package "de.vogella.scala.first".
Create the new scala object "Hello.scala".


Change the source code to the following.
package de.vogella.scala.first;
object Hello {
def main(args: Array[String]) {
println("Hello, world!")
}
}
Right-click your application, Select Runs -As -> Scala application and enjoy the output in the console.

Scala has two types of variables.
The functional programming style of Scala emphasis the usage of val variables.
Scala is a strongly typed language, e.g. each variable has a specific type. The type declaration is optional; if no type is defined during declaration then the variable will get the type of the initial assigned value. This is called "type inference".
Create a scala project "de.vogella.scala.variables" and try the following code.
object VariablesTest extends Application {
val firstName = "Lars"
val lastName = "Vogel"
var test = "changable"
println(firstName)
}
The examples are stored in project "de.vogella.scala.classexample".
A class in Scala is per default defined as public. Everything which is included in the body of the class and which is field or method definition defines the primary constructor of this class.
Here is a very simple class
package de.vogella.scala.classexample
class Robot {
val material = "steel";
}
The parameter of the primary constructor are directly defined in the class definition. Parameters are directly available within the class. To make them available outside of the class, either define a field and assign the parameter to it, or just add var or val in front of the variable in the primary constructor.
Here is an example for a class with parameters, one of them is automatically available via an accessor.
package de.vogella.scala.classexample
class Robot {
val material = "steel";
}
package de.vogella.scala.classexample
object Test extends Application {
val robot = new RobotWithConstructor (true, "steel")
robot.printStatus
// material can be accessed as it is defined via val in the primary constructor
println (robot.material)
// Status on cannot be reached, the following line would result in syntax error
// robot.on
}
Auxiliary constructors are defined via the keyword this. They have to call the primary construtor.
package de.vogella.scala.classexample
class RobotWithAuxiliaryConstructor (on: Boolean, val material:String ) {
def printStatus() = {
println(on)
println(material)
}
def this() = this(true, "Steel");
}
package de.vogella.scala.classexample
class TestAuxiliary {
val robot = new RobotWithAuxiliaryConstructor()
robot.printStatus
// material can be accessed as it is defined via val in the primary constructor
println (robot.material)
// Status on cannot be reached, the following line would result in syntax error
// robot.on
}
A class can inherit from another class via the keyword "extends".
package de.vogella.scala.classexample;
class BetterRobot (material:String) extends RobotWithConstructor (true, material ) {
}
Scala provides a very powerful extention of inheritance, traits. Traits will be covered later.
Objects are Singletons. There are for example used to represent an application.
package de.vogella.scala.classexample
object Application {
def main (args: Array[String]) {
println("The application is running")
}
}
Functions in Scala are similar to methods in Java. They are defined with the keyword "def" and have an optional parameter list and a return parameter after the ":" sign. The body of the functional is indicated by "=" and then curly braces {}
The return parameter is for a non-recursive function optional and will be determined by Scala automatically based on the function expressions. Also the curly braces for the method body are optional if the function statement has only one statement.
If a function has no parameters you can leave the () away for the call. Also the dot is not required for calling a function with only one parameter.
Create a scala project "de.vogella.scala.functions" and try the following code.
package de.vogella.scala.functions
object Function {
def main(args: Array[String]) {
println("Hello, world!")
val f = Function;
println(f.min(3,5))
println(f.min2(3,5))
// If you have no parameters you can leave the () away
f.sayHello
f.sayHello("Lars")
// You can leave away the point and if you only have one paramter also the brackets
f sayHello "Lars"
}
//Explicit return parameter
def min(i:Int, j:Int):Int = {
if (i>j)
return i
else
return j
}
//Without explicit return parameter
def min2(i:Int, j:Int) = {
if (i>j)
i
else
j
}
// One one line a body and no parameters
def sayHello = println("Hello")
// One parameter
def sayHello(s: String ) = println("Hello " + s)
}
For recursive functions you have to define the return type explicitly.
package de.vogella.scala.functions
object Factorial {
def main(args: Array[String]) {
val f = Factorial
println( f.factorial(5) )
println( f.factorial(6) )
println( f.factorial(7) )
println( f.factorial(8) )
}
def factorial (x:BigInt):BigInt= {
if (x==0) 1
else x* factorial (x-1)
}
}
Scala permits almost very sign to define a method. For example you can define a method with the name +.
As you can leave out the dot and the braces for methods with only one parameter you can write in Scala a + b and "+" is a call to your method on a with the parameter b.
override is a keyword in Scala. Everytime you override a function you have to indicate this via this keyword.
package de.vogella.scala.functions
class OverrideExample {
// Without override this would give an error
override def toString() = "test"
}
Scala supports the uniform access principle which states that it should not make a difference if the programmer access a variable directly or via a method.
The following demonstrates this. Create the Scala project "de.vogella.scala.uniformaccess".
From the client the usage of both versions of Square is the same.
package de.vogella.scala.uniformaccess
class Square {
private var l = 1 ;
var wide = 1;
def length = l;
def length_=(s : Int)= {
require (s > 0 )
this.l = s
}
}
package de.vogella.scala.uniformaccess
class Square {
var length = 1 ;
var wide = 1;
}
package de.vogella.scala.uniformaccess
object Main {
def main(args: Array[String]) {
var s = new Square();
println(s.length);
s.length = 2;
println(s.length);
}
}
Scala provides the for loop which iterates over a collection. The function foreach on a collection allows to use a closure (function) on each element.
Objects have also helper functions, for example Integer provides to to() method which allows to count from a starting number object to the defined number.
Create a scala project "de.vogella.scala.loops" and try the following code.
package de.vogella.scala.loops
object Loops {
def main(args: Array[String]) {
val list = List("Java", "Scala" , "Groovy" , "NET");
// Use foreach and print out every element
list.foreach(n=> println(n))
// Use standard for
for (n<-list){
println(n)
}
// Use method to
println
for (i<- 1.to(9)){
print (i)
}
// Use the shorter form
println
for (i<- 1 to 9){
print (i)
}
}
}
Scala provides collections, like List, Array and Map.
A List in Scala is immutatable, e.g. it is not possible to add and remove entries from a list. If you add or remove an element from a list you always create a modified copy of the original list.
package de.vogella.scala.collections;
object Lists {
def main(args: Array[String]) {
val languages = List("Java", ".NET", "C++")
println (languages)
println (languages(2))
println (languages.contains("Java"))
// + should be replaced with ::: but the Eclipse does currenlty not support this
val additionalLanguages = languages + ("COBOL")
println (additionalLanguages)
}
}
Scala also supports Arrays. In an array you can change elements. It is not possible to add elements to an Array. This operation always created a modified copy of the existing array.
package de.vogella.scala.collections
object ArrayTest {
def main(args: Array[String]) {
val languages = Array("Java", ".NET")
println (languages)
}
}
The following shows how to create Maps.
package de.vogella.scala.collections
object MapTest {
def main(args: Array[String]) {
val languages = Map("Scala"-> "JVM", "Java" -> "JVM", ".NET"-> "CLR");
println (languages("Scala"))
}
}
The following demonstrates several methods for collections. The count, filter and exists method allow to define a closure which identifies the correct element(s).
package de.vogella.scala.collections
object CollectionsMethods {
def main(args: Array[String]) {
val list= List(1, 2, 3, 4)
// Prints number of all elements
println (list.size )
// Count only the elements which can be divided by 2
println (list.count(i=> i %2==0))
// Check if a elements in included in list
println(list.exists(i=> i ==4));
println(list.exists(i=> i ==5));
// Using filter to get elements
val newList = list.filter(i=> i>=3)
println (newList)
// Map does allow to transform a list
val newList2 = list.map(i=> i*3)
println (newList2)
}
}
Scala provides case clases which have certain special properties compared with standard classes. Case classes support
Pattern matching
a factory method to created new instances of these classes without using the new keyword
the constructor arguments can be accessed using automatically generated accessor functions
The toString, equals and hashCode methods are automatically created using the constructor arguments
For example the following defines a object Person including accessors for firstName and lastName.
package de.vogella.scala.caseclasses case class Person (firstName: String, lastName:String)
This object uses the Person class.
package de.vogella.scala.caseclasses
object Main extends Application {
val p = Person("Lars", "Vogel")
println(p.toString())
println (p.firstName)
println (p.lastName)
}
Traits are similar to abstract classes you can also use them to define methods and variables. The difference is that every class in Scala can only extends one class (abstract or normal) but and can can extend / implement as many traits as it wants. By this Scala allows "multiple inheritance".
Scala multiple inheritance is safe, e.g. it doesn't have the so-called diomond problem. Scala solve this problem by a linearisation of the call path for the methods. So even if two traits implement the same method it is clean which one is called if a class implements both.
To use the trait the class extends the first trait and the other are used with the keyword "with". If the class already extends another class you use directly the keyword with.
Create a Scala project "de.vogella.scala.traits".
Create the following coding.
package de.vogella.scala.traits
trait MyTrait {
def sayHello() = println("Hello from MyTrait")
}
package de.vogella.scala.traits
trait MyTrait2 {
def sayHello() = println("Hello from MyTrait2")
def sayHello2() = println("Hello2 from MyTrait2")
}
package de.vogella.scala.traits
object TraitTest extends MyTrait with MyTrait2 {
def main(args: Array[String]) = {
sayHello
sayHello2
}
}
Scala provides several pre-defined traits which can be used. For example the "Ordered" Trait defines the method compare as abstract which the client needs to implement. The "Ordered" Trait pre-define the compare operations which can then be used directly.
Thank you for practicing with this tutorial.
I maintain this tutorial in my private time. If you like the information please help me by using flattr or donating or by
|
Before posting questions, please see the vogella FAQ . If you have questions or find an error in this article please use the www.vogella.de Google Group . I have created a short list how to create good questions which might also help you. .
http://www.scala-lang.org/ Scala Homepage
http://www.scala-lang.org/node/94 Scala IDE for Eclipse - Homepage
https://lampsvn.epfl.ch/trac/scala Scala and Eclipse IDE bug tracker
http://www.artima.com/scalazine Scala Zine from Bill Venners http://www.artima.com
http://wiki.eclipse.org/Scala_Bundle Create a Scala OSGI bundle
http://neilbartlett.name/blog/2007/04/06/an-osgi-bundle-built-in-scala/ OSGi bundle created in Scala
http://www.codecommit.com/blog/java/interop-between-java-and-scala Interoperability Between Java and Scala
http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:using_scala_to_create_eclipse_rcp_applications Using Scala to Create Eclipse RCP Applications
http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:simplifying_swt_with_scala Simplifying SWT Code with Scala