OOP Concepts in Scala
As mentioned in the introduction, Scala combines object-oriented and functional programming paradigms.
Like many other object-oriented languages, Scala provides classes
. In addition, Scala also provides
traits
.
Traits
Traits are like interfaces
, but can also define concrete methods and properties.
trait Baddie;
Abstract Methods and Properties
Traits can define abstract members that are required to be implemented by any subclass.
The following is a simple example of a purely interface-like trait, providing only abstract methods:
trait Pillager { val target: String def pillage: String } class Pirate extends Pillager { def target = "other ships" def pillage = "The pirate pillages " + target }
Concrete Methods and Properties
Traits can also provide concrete methods and properties, basically members provided to the subclass by the trait.
trait Pillager { val name: String; val target = "innocent people" def pillage = s"The $name pillages $target" } class Bandit extends Pillager { val name = "bandit" }
Mixin Composition
A class (or trait) can also extend multiple traits to combine multiple behaviors.
trait Pillager { val target: String def pillage: String } trait Sailor { def sail = "They sail" } class Pirate extends Pillager with Sailor { def target = "other ships" def pillage = "The pirate pillages " + target }
Classes
Classes are blueprints for objects. They can also extend traits or other classes (or both).
While a class can extend multiple traits, it can only extend one class. It is advisable to use traits over classes for decomposition.
Let's rewrite our previous example to use only classes.
// superclass class Pillager(val name: String) { val target = "innocent people" def pillage = s"The $name pillages $target" } // derived subclass class Bandit extends Pillager("bandit");
In this example, Pillager
is the superclass from which the Bandit
subclass is derived.
Classes can have a constructor which helps initialize values.
// Pirate is a class with one parameter, name: String// The `val` implies that the parameter is stored// as a property of the Pirate class.class Pirate(val name: String)// teach is an instance of Pirate with the name Blackbeardval teach = new Pirate("Blackbeard")
Abstract Classes
Abstract classes are similar to traits but with one big difference:
- Code with
traits
cannot be called from Java code.
Abstract classes are capable of operating with Java.
abstract class Pillager(val name: String) { def target: String def pillage = s"The $name pillages $target" } // derived subclass class Bandit extends Pillager("bandit") { val target = "innocent people" }
Implicit Classes and Extension Methods
Imagine you didn't have to explicitly construct a class to use it.
Seems convenient, yet scary, right?
Implicit classes were used in Scala 2 to add more methods to existing data types.
object stuff { def main(args: Array[String]): Unit = { "steve".mine // steve is automatically converted into a player } implicit class Player(name: String) { def mine = println(s"${name} mines!") }}
Scala 3 provides extension
methods that can work on existing data types.
extension (name: String) def mine = println(s"${name} mines!")@main def stuff(args: Array[String]): Unit = "steve".mine
Case Classes
Case classes are similar to regular classes, with more features:
- All case classes have an
apply
andunapply
method.
This means, they can be constructed without a new
keyword and
can be destroyed using a match
expression.
val origin = Coordinates(83, 10, 23)origin match { case Coordinates(x, y, z) => println(s"The altitude is ${y}!")}// CASE CLASSES HAVE// BUILT-IN EXTRACTORcase class Coordinates(x: Int, y: Int, z: Int)
Case Objects
Case objects are like case classes, but cannot be constructed.
trait Flavor;case object ButterScotch extends Flavorcase object Chocolate extends Flavorcase object Vanilla extends Flavorobject stuff { def main(args: Array[String]): Unit = { val flavor: Flavor = Chocolate flavor match { case ButterScotch => println("Tis yellow") case Chocolate => println("Tis bitter") case Vanilla => println("Tis heavenly") } }}