Fancy Parameters Class parameters  When you define a class, you typically give it parameters      Declaring a parameter with val makes the value.

Download Report

Transcript Fancy Parameters Class parameters  When you define a class, you typically give it parameters      Declaring a parameter with val makes the value.

Fancy Parameters
Class parameters

When you define a class, you typically give it parameters





Declaring a parameter with val makes the value accessible from outside the class
Declaring a parameter with var makes it accessible and changeable from outside the
class



scala> class Point(val x: Double, val y: Double)
defined class Point
scala> val p = new Point(3.7, 4.2)
p: Point = Point@452d56cc
scala> p.x
res11: Double = 3.7
Use this with extreme care—basically, only when changing the value to some garbage value
cannot cause an error
Declaring a parameter with neither val nor var makes it private to the class
(inaccessible from outside)
Note: Objects created with object (rather than from a class) don’t take parameters
2
Arbitrary number of parameters

A class can take an arbitrary number of parameters






scala> class Stuff(val things: Int*)
defined class Stuff
scala> val s = new Stuff(3, 5, 7)
s: Stuff = Stuff@6cf81618
scala> s.things
res15: Seq[Int] = WrappedArray(3, 5, 7)
scala> for (n <- s.things) print(n + " ")
3 5 7
The * notation can be used only on the last parameter
Here’s an example of a nontrivial use:


scala> var sum = 0; for (n <- s.things) sum += n
sum: Int = 15
Later we’ll learn about better ways to do things like this
3
Methods can have an arbitrary
number of parameters

scala> def vocabulary(words: String*) {
|
println("The class of \"words\" is " + words.getClass)
|
for (word <- words) println(word)
| }
vocabulary: (words: String*)Unit

scala> vocabulary("one", "two", "three")
The class of "words" is class
scala.collection.mutable.WrappedArray$ofRef
one
two
three

The type you get inside the method is a “WrappedArray,” but you can treat it as a list
(or use .toList on it)
4
case classes

When you declare a class as a case class, you get extra features
You don’t have to use new to create one

It has a better toString method (though maybe still not what you want)

Its objects can be used in match expressions
scala> case class Point(val x: Double, val y: Double)
defined class Point


scala> val p = Point(3.7, 4.2)
p: Point = Point(3.7,4.2)

scala> p match {
|
case Point(a, b) => s"It's a Point at $a, $b"
|
case _ => "It's not a Point"
| }
res21: String = It's a Point at 3.7, 4.2
You probably should only use case classes when you want the extra features, but there
seems to be little harm in overusing them
5
Named arguments to a class

scala> case class Card(suit: String, value: Int)
defined class Card



Notice that the above is a complete definition of a class
To add features to a class, you need a { on the same line
scala> val card = Card(value = 2, suit = "Clubs")
card: Card = Card(Clubs,2)

Notice that when using parameter names, the order of parameters does not matter
6
Named arguments to a method

scala> def number(hundreds: Int, tens: Int, ones: Int) =
| 100 * hundreds + 10 * tens + ones
number: (hundreds: Int, tens: Int, ones: Int)Int

scala> number(2, 3, 5)
res2: Int = 235

scala> number(tens = 3, hundreds = 2, ones = 5)
res3: Int = 235

scala> number(2, ones = 5, tens = 3)
res4: Int = 235

When you use names for only some of the arguments, the named arguments must
come after the ones in the correct position
7
Constructors


When you define a class, you are writing a constructor
A constructor is used to create new objects of a class

Create a new object (or “instance”) with the word new


You can omit the word new for a case class
When you create an object, all the “loose” code in the constructor is executed

scala> class Person(name: String) {
|
println("Creating person " + name)
|
def getName = name
| }
defined class Person

scala> val jane = new Person("Jane")
Creating person Jane

jane: Person = Person@54369a8e
scala> jane.getName
res1: String = Jane
8
Auxiliary constructors

You can have additional constructors defined within the “primary” constructor




Use the word this as the name of the constructor
The constructors must be different in the number or types of arguments
The first thing any auxiliary constructor must do is call another constructor (again,
using the word this )
scala> case class Person(val name: String, val age: Int) {
|
override def toString = s"$name is $age years old"
|
def this(name: String) {
|
this(name, 0)
|
println("It's a baby!")
|
}
| }
defined class Person
scala> new Person("Jane", 23)
res0: Person = Jane is 23 years old
scala> new Person("Frank")
It's a baby!
res1: Person = Frank is 0 years old
9
The End