Abstract Class in Scala

Scala Tutorial

Overview

A class which is declared with abstract keyword is known as abstract class.

abstract class Pet(name: String) {
var age: Int = 0 // concrete field

def printName: Unit // abstract method

def printAge: Unit = { // concrete method
println(age)
}
}

An abstract class can have both abstract and non-abstract (implemented) methods.

As mentioned, an abstract class can also have its own implemented fields and methods, which would not require implementations in sub-classes.

Note that we cannot instantiate an abstract class directly using new operator — if we do so, the compiler will throw an error!

An abstract class may be used as a base class of some other class which implements the deferred/unimplemented members.

Abstract classes can have constructor parameters as well as type parameters.

Purpose of an Abstract Class

The purpose of abstract class is to function as base class with abstractions which can be extended by subclasses to create a full implementations.

In Scala, we can achieve abstraction by using either an abstract class or a trait.

Implementing/Using Abstract Class

Use the “extends” keyword to extend an abstract class.

A class that extends an abstract class is expected to implement all the methods defined in that abstract class.

If the extending class but does not implement all the methods and fields defined in an abstract class, the extending class must be declared abstract.

Note that a class can extend only one abstract class.

class Dog(name: String) extends Pet(name) {
// Implementation of abstract method
def printName: Unit = println("Hi there, I am " + name)
}

Overriding Implemented Method

class Dog(name: String) extends Pet(name) {
// Implementation of abstract method
def printName: Unit = println("Hi there, I am " + name)

// Overrides the implemented method to add more details
override def printAge: Unit = {
println(name + "'s age is " + age)
}
}

A Complete Example

abstract class Pet(name: String) {
var age: Int = 0 // concrete field

def printName: Unit // abstract method

def printAge: Unit = { // concrete method
println(age)
}
}

class Dog(name: String) extends Pet(name) {
// Implementation of abstract method
def printName: Unit = println("Hi there, I am " + name)
}

object AbstractClassDemo extends App {
val dogObj = new Dog("Jimmy")
dogObj.printName
dogObj.age = 2
dogObj.printAge
}

Abstract “val” and “var” Fields

We can declare abstract fields in an abstract class as either valor var, depending on our needs.

abstract class Pet (name: String) {
val greeting: String // abstract "val" field
var age: Int // abstract "var" field
}

The way abstract fields work in abstract classes (also in traits) are as follows:

  • An abstract var field results in getter and setter methods being generated for the field.
  • An abstract val field results in a getter method being generated for the field, but not the setter method.

Abstract Fields Won’t Be Created!

When we define an abstract field in an abstract class or trait, the Scala compiler does not create a field in the resulting code; it only generates the methods that correspond to the val or var field.

As abstract fields are not being generated, when we provide concrete values for abstract fields in our concrete classes, we must again define the fields to be val or var.

As abstract fields don’t actually exist in the abstract base class or trait, the override keyword is not necessary.

Interoperability With Java

  • Abstract classes are fully inter-operable with Java.
  • We can call them from Java code without any wrappers.

When to Use Abstract Class Over Trait?

A trait is more flexible than an abstract class. However, one can choose abstract class over trait for the following reasons:

  • Want to create a base class that requires constructor arguments.
  • Want the code will be called from Java code.

What Can’t Be Done With an Abstract Class

Abstract classes cannot be instantiated, but they can only be sub-classed (creating sub-classes out of an abstract class).

Differences and Similarities With Java

Differences

  • No differences!

Similarities

  • Abstract classes cannot be instantiated, but they can only be sub-classed.
  • Abstract classes can have constructors.
  • A class can extend only one abstract class.