Skip to content
Snippets Groups Projects
Commit 5bb633c8 authored by Martin Odersky's avatar Martin Odersky
Browse files

Change class syntax to use

parent 466fd075
Branches with-syntax
No related tags found
No related merge requests found
......@@ -137,7 +137,7 @@ Methods for Rationals
Here's a possible implementation:
class Rational(x: Int, y: Int) {
class Rational(x: Int, y: Int):
def numer = x
def denom = y
def add(r: Rational) =
......@@ -146,7 +146,6 @@ Here's a possible implementation:
def mul(r: Rational) = ...
...
override def toString = s"$numer/$denom"
}
\red{Remark}: the modifier `override` declares that `toString`
redefines a method that already exists (in the class `java.lang.Object`).
......
......@@ -9,18 +9,16 @@ Abstract Classes
Consider the task of writing a class for sets of integers with
the following operations.
abstract class IntSet {
abstract class IntSet with
def incl(x: Int): IntSet
def contains(x: Int): Boolean
}
`IntSet` is an \red{abstract class}.
Abstract classes can contain members which are
missing an implementation (in our case, `incl` and `contains`).
Consequently, no instances of an abstract class can be created with
the operator \verb$new$.
Consequently, no instances of an abstract class can be created.
Class Extensions
================
......@@ -32,15 +30,14 @@ a tree consisting of an integer and two sub-trees.
Here are their implementations:
class Empty() extends IntSet {
class Empty() extends IntSet with
def contains(x: Int): Boolean = false
def incl(x: Int): IntSet = NonEmpty(x, Empty(), Empty())
}
Class Extensions (2)
====================
class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {
class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet with
def contains(x: Int): Boolean =
if x < elem then left.contains(x)
......@@ -51,7 +48,8 @@ Class Extensions (2)
if x < elem then NonEmpty(elem, left.incl(x), right)
else if x > elem then NonEmpty(elem, left, right.incl(x))
else this
}
end NonEmpty
Terminology
===========
......@@ -92,10 +90,9 @@ definition in a subclass by using `override`.
\example
abstract class Base { class Sub extends Base {
abstract class Base with class Sub extends Base with
def foo = 1 override def foo = 2
def bar: Int def bar = 3
} }
Object Definitions
==================
......@@ -106,10 +103,9 @@ So it seems overkill to have the user create many instances of it.
We can express this case better with an _object definition_:
object Empty extends IntSet {
object Empty extends IntSet with
def contains(x: Int): Boolean = false
def incl(x: Int): IntSet = NonEmpty(x, Empty, Empty)
}
This defines a \red{singleton object} named `Empty`.
......@@ -128,9 +124,8 @@ Each such application contains an object with a `main` method.
For instance, here is the "Hello World!" program in Scala.
object Hello {
object Hello with
def main(args: Array[String]) = println("hello world!")
}
Once this program is compiled, you can start it from the command line with
......@@ -160,11 +155,10 @@ Exercise
Write a method `union` for forming the union of two sets. You should
implement the following abstract class.
abstract class IntSet {
abstract class IntSet with
def incl(x: Int): IntSet
def contains(x: Int): Boolean
def union(other: IntSet): IntSet
}
Dynamic Binding
===============
......@@ -189,7 +183,7 @@ Another evaluation using `NonEmpty`:
`(NonEmpty(7, Empty, Empty)).contains(7)`
->
$\rightarrow$ $\btt [7/elem]\ [7/x]\ [new\ NonEmpty(7, Empty, Empty)/this]$
$\rightarrow$ $\btt [7/elem]\ [7/x]\ [NonEmpty(7, Empty, Empty)/this]$
\nl \quad$\ $ `if x < elem then this.left.contains(x)`
......
......@@ -93,11 +93,10 @@ Here, you could use `trait`s.
A trait is declared like an abstract class, just with `trait` instead of
`abstract class`.
trait Planar {
trait Planar with
def height: Int
def width: Int
def surface = height * width
}
Traits (2)
==========
......
......@@ -37,7 +37,7 @@ The `Boolean` type maps to the JVM's primitive type `boolean`.
But one _could_ define it as a class from first principles:
package idealized.scala
abstract class Boolean extends AnyVal {
abstract class Boolean extends AnyVal with
def ifThenElse[T](t: => T, e: => T): T
def && (x: => Boolean): Boolean = ifThenElse(x, false)
......@@ -47,7 +47,6 @@ But one _could_ define it as a class from first principles:
def == (x: Boolean): Boolean = ifThenElse(x, x.unary_!)
def != (x: Boolean): Boolean = ifThenElse(x.unary_!, x)
...
}
Boolean Constants
=================
......@@ -56,12 +55,11 @@ Here are constants `true` and `false` that go with `Boolean` in `idealized.scala
package idealized.scala
object true extends Boolean {
object true extends Boolean with
def ifThenElse[T](t: => T, e: => T) = t
}
object false extends Boolean {
object false extends Boolean with
def ifThenElse[T](t: => T, e: => T) = e
}
Exercise
========
......@@ -73,7 +71,8 @@ Assume for this that `false` < `true`.
->
class Boolean ...
class Boolean with
...
def < (that: Boolean) =
ifThenElse(false, that)
......@@ -84,7 +83,7 @@ The class Int
Here is a partial specification of the class `scala.Int`.
class Int {
class Int with
def + (that: Double): Double
def + (that: Float): Float
def + (that: Long): Long
......@@ -94,7 +93,6 @@ Here is a partial specification of the class `scala.Int`.
def & (that: Long): Long
def & (that: Int): Int // same for |, ^ */
}
The class Int (2)
=================
......@@ -113,13 +111,12 @@ Exercise
Provide an implementation of the abstract class `Nat` that represents non-negative integers.
abstract class Nat {
abstract class Nat with
def isZero: Boolean
def predecessor: Nat
def successor: Nat
def + (that: Nat): Nat
def - (that: Nat): Nat
}
Exercise (2)
============
......
......@@ -13,12 +13,30 @@ But what about functions?
In fact function values _are_ treated as objects in Scala.
The function type `A => B` is just an abbreviation for the class
`scala.Function1[A, B]`, which is defined as follows.
`scala.Function1[A, B]`(*), which is defined as follows.
package scala
trait Function1[A, B] {
trait Function1[A, B] with
def apply(x: A): B
(`[A, B]` are _type parameters_; we'll see them in more details in the next session).
Functions as Objects
====================
We have seen that Scala's numeric types and the `Boolean`
type can be implemented like normal classes.
But what about functions?
->
In fact function values _are_ treated as objects in Scala.
The function type `A => B` is just an abbreviation for the class
`scala.Function1[A, B]`(*), which is defined as follows.
package scala
trait Function1[A, B] with
def apply(x: A): B
}
So functions are objects with `apply` methods.
......@@ -34,16 +52,15 @@ An anonymous function such as
is expanded to:
->
{ class AnonFun() extends Function1[Int, Int]
{ class AnonFun() extends Function1[Int, Int] with
def apply(x: Int) = x * x
AnonFun()
}
->
or, shorter, using _anonymous class syntax_:
new Function1[Int, Int] {
new Function1[Int, Int] with
def apply(x: Int) = x * x
}
Expansion of Function Calls
......@@ -61,9 +78,8 @@ So the OO-translation of
would be
val f = new Function1[Int, Int] {
val f = new Function1[Int, Int] with
def apply(x: Int) = x * x
}
f.apply(7)
Functions and Methods
......@@ -82,9 +98,8 @@ converted automatically to the function value
or, expanded:
new Function1[Int, Boolean] {
new Function1[Int, Boolean] with
def apply(x: Int) = f(x)
}
Exercise
========
......
......@@ -37,9 +37,8 @@ As a simpler and shorter alternative, we
can define a type with its values in an \red{enum}:
~~~
enum Color {
enum Color with
case Red, Green, Blue, Magenta
}
~~~
This definition introduces:
......@@ -95,11 +94,10 @@ Enumerations Can Take Parameters
================================
~~~
enum Vehicle(val numberOfWheels: Int) {
enum Vehicle(val numberOfWheels: Int) with
case Unicycle extends Vehicle(1)
case Bicycle extends Vehicle(2)
case Car extends Vehicle(4)
}
~~~
- Enumeration cases that pass parameters have to use an explicit `extends` clause
......@@ -112,15 +110,15 @@ structure:
~~~
abstract class Color
object Color {
object Color with
val Red = Color()
val Green = Color()
val Blue = Color()
val Magenta = Color()
...
}
~~~
(in reality, there are some more methods defined)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment