
Scala Traits and Class Extensions Overview
Discover how Scala classes can extend both concrete and abstract members, the concept of abstract classes and single class inheritance, as well as the functionality of traits in Scala programming. Traits allow for the mixing of behaviors and state maintenance, offering a flexible approach to interface creation and class modification.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
TRAITS Tom Gant
CHAPTER 10 LOOKBACK CLASS EXTENSION Abstract classes can have both concrete and abstract/unimplemented members Can t instantiate an abstract class Blueprint for extension Sub-classes inherit non-private members of the superclass Classes can extend another single classes Single class inheritance
Object sampleProblem extends App { abstract class OtterbeinStudent { val major: String val minor: String = val GPA: Double val gradYear: Int } class Person (name: String, major1: String, GPA1: Double, gradYear1: Int, minor1: String = ) extends OtterbeinStudent{ override val major = major1 override val minor = minor1 override val GPA = GPA1 val gradYear = gradYear1 println(s Hello, my name is $name. I am a $major with a GPA of $GPA. I am supposed to graduate in $gradYear1. ) println(if (major1 == Computer Science ) { You re a Computer Science Major? Can I have your autograph? }) } val Tom = new Person ( Tom , Computer Science , 2.2, 2023) } Result1 = Hello, my name is Tom. I am a Computer Science major with a GPA of 2.2. I am supposed to graduate in 2023. Result2 = You re a Computer Science Major? Can I have your autograph?
Scala AnyRef <<java.lang.Object>> OtterbeinStudent <<abstract>> Person
WHAT IS A TRAIT (BEHAVIOR) Class definition except: Keyword trait instead of class No class parameters (Scala 3) Super calls are dynamically bound
Scala AnyRef <<java.lang.Object>> OtterbeinStudent <<abstract>> Person
WHAT IS A TRAIT (BEHAVIOR) Class definition except: Keyword trait instead of class No class parameters (Scala 3) Super calls are dynamically bound Like interfaces in Java Contains methods and fields Can be mixed in with classes and other traits
HOW TRAITS WORK Use with extend then Keyword with Keyword Scala mixes in traits rather than inherit from them Implicitly inherit the trait s superclass Traits can declare fields and maintain state Uses: create rich interfaces and provide stackable modifications to classes
Object sampleProblem extends App { abstract class OtterbeinStudent { val major: String; val minor: String = ; val GPA: Double; val gradYear: Int; } trait sportsFan { val favTeam: String } class Person (name: String, major1: String, GPA1: Double, gradYear1: Int, minor1: String = ) extends OtterbeinStudent with sportsFan{ override val major = major; override val minor = minor1; override val GPA = GPA1; val gradYear = gradYear1; val favTeam = Cincinnati! println(s Hello, my name is $name. I am a $major with a GPA of $GPA. I am supposed to graduate in $gradYear1 ) } val Tom = new Person ( Tom , Computer Science , 2.2, 2023) Tom.favTeam } Result1 = Hello, my name is Tom. I am a Computer Science major with a GPA of 2.2. I am supposed to graduate in 2023. Result2 = Cincinnati!
THIN VS RICH INTERFACES Trait inheritances adds methods ( enriches ) Trade-off with implementers (writers) and clients (user) Trait with a small number of abstract methods and a potentially large number of concrete methods Only need to implement the method once, in the trait itself
RECTANGULAR OBJECTS (EXAMPLE) Many classes representing rectangular Repetitive and inefficient Scala traits supply methods to any class
First Example class Point (val x: Int, val y: Int) class Rectangle (val topLeft: Point, val bottomRight: Point) { def left = topLeft.x def right = bottomRight.x def width = right left } Second Example abstract class Component { def topLeft: Point def bottomRight: Point def left = topLeft.x def right = bottomRight.x def width = right left } There is duplication what do we do?
USE SCALA TRAIT trait Rectangular { def topLeft: Point def bottomRight: Point def left = topLeft.x def right = bottomRight.x def width = right left //Any other methods wanted .. } abstract class Component extends Rectangular { // other methods .. } Class Rectangular (val topLeft: Point, val bottomRight: Point) extends Rectangular { // other methods .. }
ORDERED TRAIT Comparison benefits from rich interface (<=, >=) Thin interface users would: less than or equal (x < y) || (x == y) Class Rational (n: Int, d: Int){ def < (that: Rational) = this.numer * that.denom < that.numer * this.denom def > (that:Rational) = that < this def <= (that: Rational) = (this < that) || (this == that) def >= (that: Rational) = (this > that) || (this == that) }
ORDERED TRAIT (SOLUTION) Common problem Scala provides help Trait called Ordered Type passed to Ordered Mix into a class (enrich the class) 1. Define one method compare Return 1 if =, -1 if < and 1 if >0 2. Class Rational (n: Int, d: Int) extends Ordered [Rational]{ def compare (that: Rational) = (this.numer * that.denom) (that.numer * this.denom) }
STACKABLE MODIFICATIONS Traits modify methods of a class Allows stackable modifications . with keyword Example from book. Want a que of integers (FIFO) Put and get methods 3 Traits to be defined Doubling Doubles of queued integers Incrementing Increments all queued integers Filtering Filters out all negative numbers in queue.
abstract class IntQueue { def get(): Int def put(x: Int): Unit } Import scala.collection.mutable.ArrayBuffer Class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer[Int] def get() = buf.remove (0) def put(x: Int) = { buf += x} } Val queue = new BasicIntQueue queue.put (10) queue.put (20) println(queue.get()) Result = 10
trait Doubling extends IntQueue { abstract override def put(x: int) = {super.put(2 * x)} //Supers are dynamic in traits. Mixed in after concrete definition } trait Incrementing extends IntQueue { abstract override def put(x: int) = {super.put(x +1)} } trait Filtering extends IntQueue { abstract override def put(x: int) = {if (x >= 0) super.put(x)} } val queue = (new BasicIntQueue with Incrementing with Filtering) queue.put(-1); queue.put(0); queue.put(1) println(queue.get()) println(queue.get()) Result1 = 1 Result2 = 2
TRAITS VS MULTIPLE INHERITANCE Traits allow multiple inheritance Traits interpretation of super different (dynamic/static) Traits use linearization (only way to do it) val q = new BasicIntQueue with Incrementing with Doubling q.put(42)
LINEARIZATION class Animal trait Furry extends Animal trait HasLegs extends Animal trait FourLegged extends HasLegs class Cat extends Animal with Furry with FourLegged
SHOULD I USE A TRAIT? Depends Will the behavior be refused? No Concrete class Yes, in multiple unrelated classes - Trait Inherit from it in Java code Abstract class Not sure - Trait