Outdated Notice
Scala also has a concept of an abstract class that is similar to Java’s abstract class. But because traits are so powerful, you rarely need to use an abstract class. In fact, you only need to use an abstract class when:
- You want to create a base class that requires constructor arguments
- Your Scala code will be called from Java code
Scala traits don’t allow constructor parameters
Regarding the first reason, Scala traits don’t allow constructor parameters:
// this won’t compile
trait Animal(name: String)
Therefore, you need to use an abstract class whenever a base behavior must have constructor parameters:
abstract class Animal(name: String)
However, be aware that a class can extend only one abstract class.
When Scala code will be called from Java code
Regarding the second point — the second time when you’ll need to use an abstract class — because Java doesn’t know anything about Scala traits, if you want to call your Scala code from Java code, you’ll need to use an abstract class rather than a trait.
Abstract class syntax
The abstract class syntax is similar to the trait syntax. For example, here’s an abstract class named Pet
that’s similar to the Pet
trait we defined in the previous lesson:
abstract class Pet (name: String) {
def speak(): Unit = println("Yo") // concrete implementation
def comeToMaster(): Unit // abstract method
}
Given that abstract Pet
class, you can define a Dog
class like this:
class Dog(name: String) extends Pet(name) {
override def speak() = println("Woof")
def comeToMaster() = println("Here I come!")
}
The REPL shows that this all works as advertised:
scala> val d = new Dog("Rover")
d: Dog = Dog@51f1fe1c
scala> d.speak
Woof
scala> d.comeToMaster
Here I come!
Notice how name
was passed along
All of that code is similar to Java, so we won’t explain it in detail. One thing to notice is how the name
constructor parameter is passed from the Dog
class constructor to the Pet
constructor:
class Dog(name: String) extends Pet(name) {
Remember that Pet
is declared to take name
as a constructor parameter:
abstract class Pet (name: String) { ...
Therefore, this example shows how to pass the constructor parameter from the Dog
class to the Pet
abstract class. You can verify that this works with this code:
abstract class Pet (name: String) {
def speak: Unit = println(s"My name is $name")
}
class Dog(name: String) extends Pet(name)
val d = new Dog("Fido")
d.speak
We encourage you to copy and paste that code into the REPL to be sure that it works as expected, and then experiment with it as desired.
Contributors to this page:
Contents
- Introduction
- Prelude꞉ A Taste of Scala
- Preliminaries
- Scala Features
- Hello, World
- Hello, World - Version 2
- The Scala REPL
- Two Types of Variables
- The Type is Optional
- A Few Built-In Types
- Two Notes About Strings
- Command-Line I/O
- Control Structures
- The if/then/else Construct
- for Loops
- for Expressions
- match Expressions
- try/catch/finally Expressions
- Scala Classes
- Auxiliary Class Constructors
- Supplying Default Values for Constructor Parameters
- A First Look at Scala Methods
- Enumerations (and a Complete Pizza Class)
- Scala Traits and Abstract Classes
- Using Scala Traits as Interfaces
- Using Scala Traits Like Abstract Classes
- Abstract Classes
- Scala Collections
- The ArrayBuffer Class
- The List Class
- The Vector Class
- The Map Class
- The Set Class
- Anonymous Functions
- Common Sequence Methods
- Common Map Methods
- A Few Miscellaneous Items
- Tuples
- An OOP Example
- sbt and ScalaTest
- The most used scala build tool (sbt)
- Using ScalaTest with sbt
- Writing BDD Style Tests with ScalaTest and sbt
- Functional Programming
- Pure Functions
- Passing Functions Around
- No Null Values
- Companion Objects
- Case Classes
- Case Objects
- Functional Error Handling in Scala
- Concurrency
- Scala Futures
- Where To Go Next