Interfaces in Scala

Interfaces are named collections of method signatures.

import scala.math.Pi

// Here's a basic trait for geometric shapes.
trait Geometry {
  def area(): Double
  def perim(): Double
}

// For our example we'll implement this trait on
// Rect and Circle classes.
case class Rect(width: Double, height: Double) extends Geometry {
  def area(): Double = width * height
  def perim(): Double = 2 * width + 2 * height
}

case class Circle(radius: Double) extends Geometry {
  def area(): Double = Pi * radius * radius
  def perim(): Double = 2 * Pi * radius
}

// If a variable has a trait type, then we can call
// methods that are in the named trait. Here's a
// generic measure function taking advantage of this
// to work on any Geometry.
def measure(g: Geometry): Unit = {
  println(g)
  println(g.area())
  println(g.perim())
}

object InterfacesExample extends App {
  val r = Rect(width = 3, height = 4)
  val c = Circle(radius = 5)

  // The Circle and Rect case classes both
  // implement the Geometry trait so we can use
  // instances of these classes as arguments to measure.
  measure(r)
  measure(c)
}

To run the program, save it in a file named InterfacesExample.scala and use scala command:

$ scala InterfacesExample.scala
Rect(3.0,4.0)
12.0
14.0
Circle(5.0)
78.53981633974483
31.41592653589793

In Scala, we use traits to define interfaces. Traits can contain both abstract and concrete methods. Classes can extend multiple traits, which provides a form of multiple inheritance.

The case class keyword in Scala automatically provides implementations for common methods like toString, equals, and hashCode, which is why we can directly print the objects.

Scala’s object-oriented nature combined with its functional programming features make it a powerful language for defining and working with interfaces and abstract types.