classes and objects and traits and other miscellany 25-jan-16

21
Classes and Objects and Traits And Other Miscellany Jun 15, 2 022

Upload: alexia-osborne

Post on 17-Jan-2018

221 views

Category:

Documents


0 download

DESCRIPTION

Classes Syntax: class ClassName ( parameters ) { body } The class definition is the (primary) constructor Parameters and body are optional Parameters, if any, are marked with: var A var parameter will cause a field, getter, and setter to be included: var p: Int gives the methods p: () => Int and p_=: Int => () val A val parameter will create a field and a getter, but no setter Neither val nor var Can be used within the body of the class, but not create a field or any methods Generated methods may be overridden in the class

TRANSCRIPT

Page 1: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Classes and Objects and Traits

And Other Miscellany

May 3, 2023

Page 2: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Classes, objects, case classes, traits A Scala class is like a Java class

Use the class to create “objects” or “instances” of the class A Scala object is like a Java “singleton” class

If you want exactly one of a given kind of object, just define it directly; no need to create a class first

A Scala case class is just a class with extra goodies All constructor parameters are implicitly val (fields) Free implementations of equals, hashCode, toString, copy, and a

factory method Case classes support pattern matching

A Scala trait is like a Java interface Scala traits may include “concrete” methods, not just abstract ones

Scala has no special “inner classes” as in Java In Scala you can nest almost anything in anything else

Page 3: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Classes Syntax: class ClassName(parameters) { body } The class definition is the (primary) constructor

Parameters and body are optional Parameters, if any, are marked with:

var A var parameter will cause a field, getter, and setter to be included:

var p: Int gives the methods p: () => Int and p_=: Int => () val

A val parameter will create a field and a getter, but no setter Neither val nor var

Can be used within the body of the class, but not create a field or any methods Generated methods may be overridden in the class

Page 4: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Constructors The class definition is the primary constructor

When creating a new object, the code within the class is executed

Auxiliary (additional) constructors have the syntax def this(parameters) {

call to a constructor declared earlier (this is required) rest of code}

Calling a constructor is just as in Java new Person("Dave")

Page 5: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Examples I scala> class Person(val firstName:String, var lastName: String, age: Int)

defined class Person scala> val mary = new Person("Mary", "Smith", 23)

mary: Person = Person@d73c3c scala> mary.firstName

res22: String = Mary scala> mary.lastName

res23: String = Smith scala> mary.firstName = "Sally"

<console>:7: error: reassignment to val scala> mary.lastName = "Jones"

res24: String = Jones scala> mary.age

<console>:8: error: value age is not a member of Person scala> mary.lastName

res25: String = Jones

5

Page 6: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Examples II Again, but this time with a method:

scala> class Person(val firstName:String, var lastName: String, age: Int) { | override def toString = firstName + " " + lastName + ", age " + age | }defined class Person

scala> val mary = new Person("Mary", "Smith", 23)mary: Person = Mary Smith, age 23

scala> println(mary)Mary Smith, age 23

6

Page 7: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Object An object is defined similar to the way that a class is

defined, but it cannot take parameters Syntax: object ObjectName { body } A program’s main method is defined in an object:

def main(args: Array[String]) { body } This is exactly analogous to Java’s main method

public static void main(String[] args) { body }

Page 8: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Companion objects Scala’s equivalent of static is the companion object The companion object of a class

has the same name as the class is defined in the same file as the class

The object and class can access each other’s private fields and methods

In the class, access to the fields and methods in the companion object must be qualified with the name of the object

Page 9: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Abstract classes To define a method as abstract, simply omit its body To define a field as abstract, omit its initial value A class containing abstract methods or fields must be

declared abstract As in Java, an abstract class is one that cannot be

instantiated In a concrete subclass, you do not need the override

keyword

Page 10: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Case classes Syntax: case class ClassName(parameters)

{ body } All the parameters are implicitly val

A parameter can be explicitly declared as var (not recommended) toString, equals, hashCode, and copy are generated

(unless you supply them) apply and unapply are also generated

apply lets you omit the word new when you create objects unapply lets you use the objects in pattern matching

Page 11: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Case classes can be pattern matched scala> case class Person(age: Int, name: String)

defined class Person

scala> val dave = Person(40, "Dave")dave: Person = Person(40,Dave)

scala> dave match { | case Person(a, n) if a > 30 => println(n + " is old!") | case _ => println("Whatever") | }Dave is old!

scala> val quinn = Person(25, "Quinn")quinn: Person = Person(25,Quinn)

scala> quinn match { | case Person(a, n) if a > 30 => println(n + " is old!") | case _ => println("Whatever") | }Whatever

Page 12: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Case classes in pattern matching sealed abstract class Move

case object Left extends Move case object Right extends Move case object Up extends Move case object Down extends Move

direction match { case Left => x -= 1 case Right => x += 1 case Up => y -= 1 case Down => y += 1}

Page 13: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Traits Traits are like Java’s interfaces Syntax: trait TraitName { body } Unlike Java, traits may have concrete (defined) methods

A class extends exactly one other class, but may with any number of traits

Syntax: class ClassName(parameters) extends OtherClass with

Trait1, …, TraitN { body } class ClassName(parameters) extends Trait1 with Trait2,

…, TraitN { body }

Page 14: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Pattern matching with match You have seen pattern matching with match and literals

today match { case "Saturday" => println("Party! Party! Party!") case "Sunday" => println("Pray....") case day => println(day + " is a workday. :( ")}

You can match with types something match {

case x: Int => println("I'm the integer " + x) case x: String => println("I'm the String \"" + x + "\"") println("My length is " + x.length) case _ => println("I don't know what I am! :( ") }

Page 15: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Pattern matching in assignments You can pattern match on tuples:

scala> val (a, b, c) = (3, 5, 7)a: Int = 3b: Int = 5c: Int = 7

But… scala> val a, b, c = (3, 5, 7)

a: (Int, Int, Int) = (3,5,7)b: (Int, Int, Int) = (3,5,7)c: (Int, Int, Int) = (3,5,7)

You can pattern match on lists: scala> val list = List("once", "upon", "a", "time")

list: List[java.lang.String] = List(once, upon, a, time) scala> val first :: second :: rest = list

first: java.lang.String = oncesecond: java.lang.String = uponrest: List[java.lang.String] = List(a, time)

Page 16: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Operations and methods

16

As operation As method callUnary prefix scala> -5

res4: Int = -5scala> 5 unary_-res5: Int = -5

Unary scala> " abc " trimres6: java.lang.String = abc

scala> " abc ".trim()res7: java.lang.String = abc

Binary scala> "abc" + "xyz"res8: java.lang.String = abcxyz

scala> "abcdef" substring 2res10: java.lang.String = cdef

scala> "abc".+("xyz")res9: java.lang.String = abcxyz

scala> "abcdef".substring(2)res11: java.lang.String = cdef

>2 operands scala> "abcdef" substring (1, 3)res12: java.lang.String = bc

scala> "abcdef".substring(1, 3)res13: java.lang.String = bc

Page 17: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Parameters in braces A block consists of any number of statements inside braces, { }

The last value in the block is the value of the block Parentheses, ( ), can’t enclose multiple statements

When a method takes just one parameter, you can put that parameter inside braces instead of parentheses

scala> "abcdefg" substring { 2 }res0: java.lang.String = cdefg

This example is pointless and looks silly Sometimes, you may want to compute that parameter by a series of statements

scala> println { | var x = 2 | while (x < 1000) x *= 2 | x | }1024

This isn’t a great example either, but it does make the point

17

Page 18: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Methods with no parameters You can define a “parameterless” method:

scala> def hello = println("Hello!")hello: Unit

scala> helloHello!

scala> hello()<console>:7: error: hello of type Unit does not take parameters

You can define an “empty paren” method: scala> def hi() = println("Hi!")

hi: ()Unit scala> hi

Hi! scala> hi()

Hi! If you define a method without parentheses, you can’t call it with parentheses You can replace a parameterless method with an empty paren method, without

affecting user code (but not vice versa)

18

Page 19: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Uniform access In Java, the length of an array is a field, so you have to say

myArray.length; but the length of a String is a field, so you have to say myString.length()

This violates the principle of uniform access: The user shouldn’t have to know whether it’s a field or a method

However, if I say foo = bar, or println(bar), I am using bar like a variable, so I expect bar to act like a variable:

bar should not do I/O bar should not change mutable state bar should not depend on values in mutable state

In other words, if bar is a function, it should be a pure function Scala convention: When you call a method that does one of the

above (impure) things, use parentheses19

Page 20: Classes and Objects and Traits And Other Miscellany 25-Jan-16

Types Types can be “aliased” (named)

type Word = Stringtype Sentence = List[Word]type Paragraph = List[Sentence]

This is a simple thing that can be extremely helpful when dealing with complex data types

Page 21: Classes and Objects and Traits And Other Miscellany 25-Jan-16

The End