Classes: Members and Accessor Methods (Getters) (Scala 3 Video)
Classes can have members, which are fields and methods.
Here’s an OOP example:
import scala.collection.mutable.ArrayBuffer
class Pizza(
val crustSize: CrustSize = Medium,
val crustType: CrustType = Regular
):
// a private field
private val toppings = ArrayBuffer[Topping]()
// members inside the class
def addTopping(t: Topping): Unit =
toppings += t
def addToppings(ts: Topping*): Unit =
toppings.appendAll(ts)
def removeAllToppings(): Unit =
toppings.clear()
override def toString = s"""
|A $crustSize pizza with a $crustType crust.
|Toppings: ${p.toppings.mkString(", ")}""".stripMargin
end Pizza
Fields in a class
To demonstrate field in a class, here are a few enums (enumerations) to help us get started:
enum CrustSize:
case Small, Medium, Large
enum CrustType:
case Thin, Thick, Regular
enum Topping:
case Cheese, Mushrooms, GreenPeppers, Olives
import CrustSize.*
import CrustType.*
import Topping.*
Given those enums, you can create a Pizza
class like this:
// [1] can do this
class Pizza(
var crustSize: CrustSize,
var crustType: CrustType,
val toppings: ArrayBuffer[Topping]
)
But to demonstrate fields, you can also use fields for those values:
// [2] can also do this
import scala.collection.mutable.ArrayBuffer
class Pizza:
var crustSize = Medium
var crustType = Regular
val toppings = ArrayBuffer[Topping]()
Given that second class, this example shows how to create a pizza and update the values of those fields:
val p = Pizza()
p.crustSize = Large
p.crustType = Thin
p.toppings ++= Seq(Cheese, Mushrooms)
Note that I mutate the ArrayBuffer directly there
Member visibility
You can also control the possibility of members. They are public by default, and you can make them private or protected.
A good question in the following example is, “Should toppings
be publicly accessible?”
import scala.collection.mutable.ArrayBuffer
class Pizza:
var crustSize = Medium
var crustType = Regular
private val toppings = ArrayBuffer[Topping]()
-------
That is, do you want other people to have direct access to your ArrayBuffer
? For me, the answer is no, so we make toppings
private.
The fact that
toppings
is implemented as anArrayBuffer
is an implementation detail that we don’t want to leak out to people who use our class.
Methods in a class
Scala classes can also have methods, as shown in this example:
import scala.collection.mutable.ArrayBuffer
class Pizza(
val crustSize: CrustSize = Medium,
val crustType: CrustType = Regular
):
private val toppings = Seq[ArrayBuffer]()
def addTopping(t: Topping): Unit =
toppings += t
def addToppings(ts: Topping*): Unit =
toppings.appendAll(ts)
def removeAllToppings(): Unit =
toppings.clear()
override def toString = s"""
|A $crustSize pizza with a $crustType crust.
|Toppings: ${p.toppings.mkString(", ")}""".stripMargin
end Pizza
You can then create a Pizza
:
// either of these will work
val p = Pizza()
val p = Pizza(Medium, Regular)
Update the values in its fields:
p.crustSize = Large
p.crustType = Thin
p.toppings
And call those methods:
p.addTopping(Cheese)
p.addToppings(Mushrooms, Olives)
p.removeAllToppings()