Classes and objects
In Scala, a class is a blueprint for objects. Once you define a class, you can create objects from the class blueprint with the keyword new. Through the object you can use all functionalities of the defined class.
An object is a named instance with members such as fields and methods. It is a class that has exactly one instance. There are three uses of objects.
- Contain fields and methods that are independent of any environment;
object Math {
def divide(x: Int, y: Int) = x / y
def square(x: Int) = x*x
}
println(Math.square(3))
println(Math square 3) // works if there is only one augment
- Create instances of classes with the keyword
new
;
class Circle(radius: Double) {
def area: Double = calculateArea(radius)
}
object Circle {
private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)
}
val circle1 = new Circle(5.0)
println(circle1.area)
An object with the same name as a class is called a companion object. Conversely, the class is the object’s companion class. A companion class or object can access the private members of its companion. Use a companion object for methods and values which are not specific to instances of the companion class.
- Create the entry point to a Scala program by defining a
main
method with a specific signature.
object <object name> {
def main(args: <arg type>) = {
}
}
class User(var name: String, var age: Int);
object Demo {
def main(args: Array[String]) {
var user = new User("Max", 28);
println(user.name);
println(user.age);
user.name = "Tom"; // rewritable because name is var
user.age = 23;
println(user.name);
println(user.age);
}
}
// Getter? Setter?
// ------- ------- ---------
// var yes yes
// val yes no
// default no no
// you cannot access name outside the class if it's private
class User2(private var name: String, var age: Int) {
def printName{ println(name) }
};
var user2 = new User2("Max", 28);
println(user2.name); // returns error
// to access name inside a class
user2.printName
Class Hierarchies
Auxiliary constructor
An alternative constructor for a class.
With primary constructors, you must have different signatures for your auxiliary constructors; you must call previously defined constructors in your auxiliary constructors.
class User(val name: String, var age: Int) { // primary constructor
def this() { // auxiliary constructor
this("Tim", 21);
}
def this(name: String) {
this(name, 32);
}
}
object Demo{
def main(args: Array[String]) {
var user1 = new User("Max", 28);
var user2 = new User();
var user3 = new User("Max");
}
}
Class inheritance: extending a class
Scala doesn’t allow multiple inheritance from more than one class.
A super class Polygon:
package Inheritance
class Polygon {
def area: Double = 0.0;
}
object Polygon {
def main(args: Array[String]) {
var poly = new Polygon;
printArea(poly);
var rect = new Rectangle(55.2, 20.0);
printArea(rect);
var tri = new Triangle(55.2, 20.0);
printArea(tri);
}
def printArea(p: Polygon) {
println(p.area);
}
}
A subclass Rectangle:
package Inheritance
class Rectangle(var width: Double, var height: Double) extends Polygon {
override def area: Double = width * height;
}
A subclass Triangle:
package Inheritance
class Triangle(var width: Double, var height: Double) extends Polygon {
override def area: Double = width * height / 2;
}
override
redefines an existing, non-abstract definition in a subclass.
Abstract class
An abstract class can contain members which are missing an implementation. Consequently, it cannot be instantiated with the operator new
.
An abstract class does a few things for the inheriting subclass:
- define methods which can be used by the inheriting subclass;
- define abstract methods which the inheriting subclass must implement, in another word, it makes sure that we must implement methods inside subclasses;
- provide a common interface which allows the subclass to be interchanged with all other subclasses i.e. inheritance.
package Inheritance
abstract class Polygon {
def area: Double; // doesn't provide any body to this method
}
object Polygon {
def main(args: Array[String]) {
// var poly = new Polygon; // cannot be instantiated
// printArea(poly);
var rect = new Rectangle(55.2, 20.0);
printArea(rect);
var tri = new Triangle(55.2, 20.0);
printArea(tri);
}
def printArea(p: Polygon) {
println(p.area);
}
}
Trait
Scala doesn’t allow multiple inheritance and instead they use interface. A trait is a partially created interface.
package Inheritance
trait Shape {
def shape: String;
}
class Rectangle(var width: Double, var height: Double) extends Polygon with Shape {
override def area: Double = height * width;
def shape: String = "rectangle"; // can remove override when inheriting from a trait
}