Object Oriented Programming
Basic
class Person(name: String) // constructor
val person = new Person("John")
Parameters vs Fields
Class parameters can't be accessed by . because they aren't class fields. For example, person.name isn't working.
To create a class field, we need to use val or var.
class Person(name: String, val age: Int)
val person = new Person("John", 26)
println(person.age) // works. Because age is a class field.
Body
class Person(name: String, val age: Int) {
// body
// fields
val x: Int = 2
// methods
def greet(name: String): Unit = println($"Hi $name.")
// Overloading
def greet(): Unit = println($"I'm ${this.name}. I'm ${this.age} years old.")
}
val person = new Person("John", 26)
println(person.x) // works.
- When an instance is initialized, all the codes in the body are run.
valValues in the body are class fields.thispoints to both class fields and methods.- In general, overloading methods works in Scala except one case, which is two methods have the same name and parameters but return different types of data.
Immutability
Immutability is very important in Functional Programming.
When you need to modify the contents of an instance, you create a new instance.
class Counter(val num: Int) {
def increase(n: Int = 1) = new Counter(this.num + n)
def decrease(n: Int = 1) = new Counter(this.num - n)
}
Operators
All operators in Scala are methods.
val num = 1 + 2
val num = 1.+(2) // equivalent
Therefore, we can override or create an operator.
class Person(val: name) {
def worksWith(person: Person): String = s"${this.name} works with ${person.name}."
def +(person: Person): String = s"${this.name} works with ${person.name}."
}
val jack = new Person("Jack")
val paul = new Person("Paul")
println(jack + paul) // Jack works with Paul.
println(jack worksWith paul) // Jack works with Paul.
There is a very special method in Scala Class, apply.
class Person(val: name) {
def apply(): String = s"I'm ${this.name}."
def apply(val greeting: String): String = s"$greeting, I'm ${this.name}."
}
val mary = new Person("Mary")
mary.apply() // I'm Mary.
mary() // I'm Mary.
mary.apply("Hi") // Hi, I'm Mary
mary("Hi") // Hi, I'm Mary
apply method breaks the barrier between OOP and Functional Programming. So it's heavily used in Scala.
Notation
class Person(val name: String) {
// infix notation
def worksWith(person: Person): String = s"${this.name} works with ${person.name}."
// prefix notation
def unary_!(): String = s"${name.toUpperCase()}!"
// postfix notation
def isAlive(): Boolean = true;
// apply
def apply(): String = s"I'm ${this.name}."
}
-
Infix notion
jack.worksWith(paul) jack worksWith paul // equivalentIt only works on the method with ONE parameter.
-
prefix notion
jack.unary_!() !jack // equivalentIt only works with
+,-,~,!. -
postfix notation
jack.isAlive() jack isAlive // equivalentIt only works on the method with NO parameters.
-
apply
The special method let us call the instance of a class as a function.