Scala Learning Series
Abstract Class in Scala
Scala Programming
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 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 val
or 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.