8.6. Marking Traits So They Can Only Be Used by Subclasses of a Certain Type
Problem
You want to mark your trait so it can only be used by types that extend a given base type.
Solution
To make sure a trait named MyTrait
can only be mixed into a class that is
a subclass of a type named BaseType
,
begin your trait with a this: BaseType
=>
declaration, as shown here:
trait
MyTrait
{
this:
BaseType
=>
For instance, to make sure a StarfleetWarpCore
can only be used in a
Starship
, mark the StarfleetWarpCore
trait like this:
trait
StarfleetWarpCore
{
this:
Starship
=>
// more code here ...
}
Given that declaration, this code will work:
class
Starship
class
Enterprise
extends
Starship
with
StarfleetWarpCore
But other attempts like this will fail:
class
RomulanShip
// this won't compile
class
Warbird
extends
RomulanShip
with
StarfleetWarpCore
This second example fails with an error message similar to this:
error: illegal inheritance; self-type Warbird does not conform to StarfleetWarpCore's selftype StarfleetWarpCore with Starship class Warbird extends RomulanShip with StarfleetWarpCore ^
Discussion
As shown in the error message, this approach is referred to as a self type. The Scala Glossary includes this statement as part of its description of a self type:
“Any concrete class that mixes in the trait must ensure that its type conforms to the trait’s self type.”
A trait can also require that any type that wishes to extend it
must extend multiple other types. The following WarpCore
definition requires that ...
Get Scala Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.