Scala Tutorial
Basics
Control Statements
OOP Concepts
Parameterized - Type
Exceptions
Scala Annotation
Methods
String
Scala Packages
Scala Trait
Collections
Scala Options
Miscellaneous Topics
In Scala, inheritance allows a class to inherit members (fields and methods) from another class. Scala, like Java, supports single class inheritance, meaning a class can inherit from only one superclass. However, Scala provides traits (similar to Java's interfaces but more powerful) that allow for multiple inheritance-like behavior.
Let's dive into inheritance in Scala:
A class inherits from another class using the extends
keyword:
class Animal { def speak(): Unit = println("Some sound") } class Dog extends Animal { override def speak(): Unit = println("Woof!") }
In the above example, Dog
is a subclass of Animal
, and it overrides the speak
method.
If the superclass has a constructor, the subclass needs to call it using the extends
keyword:
class Animal(name: String) { def speak(): Unit = println(s"$name makes a sound") } class Dog(name: String) extends Animal(name) { override def speak(): Unit = println(s"$name says Woof!") }
When a subclass provides a new implementation for an inherited member, it uses the override
keyword:
class Animal { val sound: String = "Some sound" def speak(): Unit = println(sound) } class Dog extends Animal { override val sound: String = "Woof!" }
In Scala, a class can be declared abstract
. Abstract classes cannot be instantiated, and they can have abstract members (members without implementations):
abstract class Animal { def speak(): Unit } class Dog extends Animal { def speak(): Unit = println("Woof!") }
The final
keyword can be used to prevent a member from being overridden in subclasses or to prevent a class from being subclassed:
class Animal { final def speak(): Unit = println("Some sound") } // The following will cause a compile-time error class Dog extends Animal { override def speak(): Unit = println("Woof!") }
Traits are a powerful feature in Scala that allows for multiple inheritance. A class can extend multiple traits using the extends
and with
keywords:
trait Carnivore { def eat(meat: String): Unit } trait Mammal { def speak(): Unit } class Dog extends Mammal with Carnivore { def speak(): Unit = println("Woof!") def eat(meat: String): Unit = println(s"Eats $meat") }
Inheritance in Scala provides a way to create a new class as a modified version of an existing class. By leveraging abstract classes, overriding members, and incorporating traits, Scala offers a flexible and expressive inheritance model. However, always consider composition as an alternative to inheritance; it can lead to more modular and maintainable code in many situations.
Scala class hierarchy and inheritance:
class Animal { def sound(): String = "Some generic sound" } class Dog extends Animal { override def sound(): String = "Woof!" }
Single inheritance in Scala:
class A class B extends A // Single inheritance
Scala extends
keyword usage:
extends
keyword is used to declare that a class is inheriting from another class.class Animal class Dog extends Animal
Superclass and subclass relationships in Scala:
class Vehicle { def start(): String = "Vehicle started" } class Car extends Vehicle { // Inherits start() method }
Overriding methods in Scala:
class Animal { def sound(): String = "Some generic sound" } class Dog extends Animal { override def sound(): String = "Woof!" }
Abstract classes and inheritance in Scala:
abstract class Shape { def area(): Double } class Circle(radius: Double) extends Shape { override def area(): Double = math.Pi * radius * radius }
Traits and mixin composition in Scala:
trait Flyable { def fly(): String = "Flying high" } class Bird extends Flyable
Multiple inheritance with traits in Scala:
trait Swimmable { def swim(): String = "Swimming gracefully" } class Duck extends Flyable with Swimmable
Linearization of traits in Scala:
trait A { def message: String } trait B extends A { override def message: String = "B" } trait C extends A { override def message: String = "C" } class D extends B with C
Mixing traits and abstract classes in Scala:
abstract class Animal { def sound(): String } trait Jumpable { def jump(): String = "Jumping" } class Kangaroo extends Animal with Jumpable { override def sound(): String = "Boing!" }
Initialization order in Scala inheritance:
class A { println("A") } trait B extends A { println("B") } class C extends A with B { println("C") } val obj = new C // Output: A B C
Access modifiers in Scala inheritance:
private
, protected
, and public
modifiers.class A { private val privateField = 42 protected val protectedField = "Protected" val publicField = true } class B extends A { // Can access protectedField but not privateField def printFields(): Unit = println(s"$protectedField, $publicField") }
Delegation vs. inheritance in Scala:
// Delegation class Printer { def print(message: String): Unit = println(message) } class Report(printer: Printer) { def generate(): Unit = { // Generate report printer.print("Report generated") } }