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" }

Enums

Scala 3 allows enums, to define types that can have a defined set of values.

 enum IceCream:   case Choco, Vanilla, Butterscotch val snack = IceCream.Butterscotch snack match {   case IceCream.Choco => println("It is chocolate!")   case IceCream.Vanilla => println("It is vanilla!")   case IceCream.Butterscotch => println("It is butterscotch!") }