% CSE 130: Fall 2012
% Objects, Classes & Inheritance 
% Ranjit Jhala, UC San Diego 

# What is an Object?

## What is an object?

Here's a really simple object

~~~~~{.scala}
object countUp {
  var count = 0         // Data
  
  def next() = {        // Function 
    count += 1 
    count 
  }

  def hasNext = true    // Function 
}
~~~~~

>- Object     = Map from Names To Properties
>- Names      = `count`, `next`, `hasNext`
>- Properties = Data + Functions


## What is an object

Just a fancy *value* 

- **Object**     = Map from **Names** To **Properties**
- **Properties** = Data + Functions


# So, how can we USE an Object?
 

## So, how can we USE an Object?

Here's a client function:

~~~~~{.scala}
scala> def tickN(it: Any, n: Int) = 
         for (i <- 1 to n){ println(it.next()) }

scala> tickN(countUp, 5)
~~~~~

What happens?

**A.** prints out `1 2 3 4 5`

**B.** prints out `1\n 2\n 3\n 4\n 5\n`

**C.** run-time exception

**D.** type error at function definition `def tickN ...`

**E.** type error at function call `tickN(countUp, 5)`


## So, how can we USE an Object?

Here's a client function:

~~~~~{.scala}
def tickN(it: Any, n: Int) = 
   for (i <- 1 to n){println(it.next())}
~~~~~

Type checker is **not happy**.

~~~~~{.scala}
<console>:9: error: value next is not a member of Any
            println(it.next())
                       ^
~~~~~

# How to DESCRIBE the Required Properties ?

## QUIZ: How to DESCRIBE the Required Properties ?

~~~~~{.scala}
def tickN(it: Any, n: Int) = 
   for (i <- 1 to n){println(it.next())}

<console>:9: error: value next is not a member of Any
            println(it.next())
                       ^
~~~~~

### Cannot call `tickN` with `Any` value...

Which properties **are required by** `tickN` ?

**A.** `count`

**B.** `next`

**C.** `hasNext`

**D.** `next` and `hasNext`

**E.** all of the above

## Describing Objects with "Structural" Types

The mystery type `???`

~~~~~{.scala}
def tickN(it: ???, n: Int) = 
   for (i <- 1 to n){println(it.next())}
~~~~~

`it` must be an object ...

... that maps the name `next` 

... to a function that takes `()` and returns something.

~~~~~{.scala}
{ def next(): Any }
~~~~~

>- Called a **Structural** Type

>- Describes requirements on structure ...

## Need to DESCRIBE the TYPE of an object?

~~~~~{.scala}
def tickN(it: { def next(): Any}, n: Int) = 
   for (i <- 1 to n){println(it.next())}
~~~~~

Thats it! 

Lets take it for a spin.

~~~~~{.scala}
scala> tickN(countUp, 5)
1
2
3
4
5
~~~~~

## Recap

>- Object = Names -> Properties

>- Type   = Names -> Types 

## What is an object?

Here's another really simple object

~~~~~{.scala}
object countFib {
  var a = 0             // Data
  var b = 1             // Data

  def next() = {        // Function 
    val (a0, b0) = (b, a + b) 
    a = a0
    b = b0
    a 
  }

  def hasNext = true    // Function 
}
~~~~~

- **Object**     = Map from Names To Properties
- **Names**      = `a`, `b`, `next`, `hasNext`
- **Properties** = Data + Functions

## QUIZ: So, how can we USE an Object?

~~~~~{.scala}
object countFib {
  var a = 0             // Field 
  var b = 1             // Another Field! 
  def next() = {        // Method 
    val (a1, b1) = (b, a + b) 
    a = a1
    b = b1
    a }
  def hasNext = true    // Another Method! }
~~~~~

What happens if we try `tickN(countFib, 5)` ?

**A.** prints out `1 1 2 3 5`

**B.** prints out `1\n 1\n 2\n 3\n 5\n`

**C.** run-time exception

**D.** type error in `def tickN ...`

**E.** type error in `tickN(countFib, 5)`


## So, how can we USE an Object?

We can use it with `tickN` too!

~~~~~{.scala}
scala> tickN(countFib, 10)
1
2
3
5
8
13
21
34
55
89
~~~~~

`tickN` doesn't care about **extra** names and properties


## So, how can we USE an Object?

`tickN` can be called with **any** object with suitable `next`  

- A **structural** subtype of `{def next():Any}`

~~~~~{.scala}
scala> tickN("yellowmattercustard".iterator, 5)
y
e
l
l
o
~~~~~


## So, how can we USE an Object?

`tickN` can be called with *any* object with suitable `next`  

~~~~~{.scala}
scala> tickN(List("cat", "dog").iterator, 5)

cat
dog

java.util.NoSuchElementException: next on empty iterator
~~~~~

Whoops.


## So, how can we USE an Object?

We can add more **required** methods to `tickN`

~~~~~{.scala}
def tickN(it: {def next(): Any; def hasNext: Boolean}, n: Int) = 
  for (i <- 1 to n){
    if (it.hasNext) println(it.next())
  }
~~~~~

## So, how can we USE an Object?

We can add more **required** methods to `tickN`

Better to give the new required type a name

~~~~~{.scala}
type ticker = { def next(): Any; def hasNext: Boolean }
~~~~~

and then ...

~~~~~{.scala}
def tickN(it: ticker, n: Int) = 
  for (i <- 1 to n){
    if (it.hasNext) {
      println(it.next()) 
    } else {
      println("Out of Stuff!")
    }
  } 
~~~~~

## So, how can we USE an Object?

Which works quite nicely...

~~~~~{.scala}
scala> tickN(List("cat", "dog").iterator, 5)
cat
dog
Out of Stuff!
Out of Stuff!
Out of Stuff!
~~~~~

## Recap

Objects

- Maps from **names** to **properties** 

- Properties = Data + Functions (+ Objects)

Types 

- Short descriptions of Objects

- Maps from **names** to **types**

- **Structural** Types

## So thats OOP! (?)

What else do we need?

# What IS a **class** Anyway?

## What IS a **class** Anyway?

Seem to be doing just fine without them!

Many OO languages are **Class**-less 

>- Google's [Go](http://www.infoq.com/interviews/pike-google-go)

>- JavaScript (also type-less ...)

>- Java-- (only interfaces) 

## Why do we need Classes?

You tell me!

- ???

- ???

- ???

- ???


## What is a Class?

Unified mechanism for two tasks

<img src="../static/twobirds.jpg" width=200 align="middle"/> 

### Specification 

A **name** for **describing** contents 

### Implementation

A **template** for **creating** new objects


## What is a Class?

Spectrum from Specification to Implementation

### 1. Interfaces

> - **Only** Specification of  Types

### 2. Abstract Class

> - Specification + **Some** Concrete Implementations

### 3. Class

> - Specification + **All** Concrete Implementations

# The Class Spectrum in Scala: Interfaces

## The Class Spectrum in Scala: Interfaces

### Interfaces: Only Specify Type

~~~~~{.scala}
type ticker = { def next(): Any; def hasNext: Boolean }
~~~~~

Some other ways too (later.)

# The Class Spectrum in Scala: Abstract Classes

## The Class Spectrum in Scala: Abstract Classes

Lets make a [ScreenSaver!](/static/ScreenSaver.scala)

Here's the basic loop for the graphics:

~~~~~{.scala}
def run(box: JPanel, points: List[Point]) {
  ...
  while (true) {
    for (p <- points) {
      p.draw(g)             
      p.move(d, delta)
      p.collide(d)
    }
  }
  ...
}
~~~~~

Need a type `Point` describing objects that we can:

- `draw`, `move`, `collide` 

## The Class Spectrum in Scala: Abstract Classes

Need a type describing `draw`, `move`, `collide` 

First, some essential fields...

~~~~~{.scala}
abstract class Point {
 
 // Must be filled in by (concrete) sub-classes
  val name : String     // immutable
  var x    : Int        // mutable
  var y    : Int        // mutable
 
 // Defined, but may be "overridden" by sub-classes
  var xVel = Rand(1, 5) 
  var yVel = Rand(1, 5) 
  ...
}
~~~~~

## The Class Spectrum in Scala: Abstract Classes

Need a type describing `draw`, `move`, `collide` 

Next, the methods ...

~~~~~{.scala}
abstract class Point {
  // Must be filled in by (concrete) sub-classes
  def xDim : Int
  def yDim : Int
  def render(g: Graphics): Unit
  def move(d: Dimension, delta: Int) 
  ... 
}
~~~~~

... these are pure specification

**must** be filled in by any actual `Point` object

## The Class Spectrum in Scala: Abstract Classes

Need a type describing `draw`, `move`, `collide` 

Next, we **specify** the methods ...

~~~~~{.scala}
abstract class Point {
  // Must be filled in by (concrete) sub-classes
  def xDim : Int
  def yDim : Int
  def render(g: Graphics): Unit
  def move(d: Dimension, delta: Int) 
  ... 
}
~~~~~

... which **must** be filled in an actual `Point` object

## The Class Spectrum in Scala: Abstract Classes

Need a type describing `draw`, `move`, `collide` 

Finally, we **implement**  a few common methods ...

~~~~~{.scala}
abstract class Point {
  
  // Can be overridden by concrete Points
  def collide(d: Dimension) {
    hitWall(x, 0, d.width - xDim) map {(v:Int) => 
      x    = v 
      xVel = -xVel 
    } ...
  }
  
  // Cannot be overridden by sub-classes
  final def draw(g: Graphics) {
    val c = g.getColor()    // save old color
    render(g)               // render object
    g.setColor(c)           // restore old color
  }
}
~~~~~

... which **must** be filled in an actual `Point` object


## Screensaver `Point` only needs `collide`, `draw` and `move`.

Which of the following are type-safe modifications to `Point`? 


**A.** Delete the specification of `x` and `y` 

**B.** Delete the specification of `collide`

**C.** Delete the implementation of `collide`

**D.** Do both (A) and (C)

**E.** All of the above

# So, how do we create a real `Point` ?!

# The Class Spectrum in Scala: (Concrete) Classes

## The Class Spectrum in Scala: (Concrete) Classes

Like an `abstract` class but with **everything** defined.

~~~~~{.scala}
class Dot(val name: String, x0: Int, y0: Int) extends Point {
    ...
}
~~~~~

`extends Point` says `Dot` is a concrete implementation of `Point`.

## The Class Spectrum in Scala: Classes

Parameters define several things "for free"

~~~~~{.scala}
class Dot(val name: String, x0: Int, y0: Int) extends Point {
  // Filled in by "constructor"
  var x     = x0 
  var y     = y0 
  def xDim  = 20
  def yDim  = 20
  ...
}
~~~~~

Generated Constructor 

- Initializes fields from parameters `x0`, `y0`

- Named parameters automatically become fields

## The Class Spectrum in Scala: Classes

We define required methods

~~~~~{.scala}
class Dot(val name: String, x0: Int, y0: Int) extends Point {
  def render(g: Graphics) {
    g.fillOval(x, y, xDim, yDim)
  }
 
  override def move(d: Dimension, delta: Int) {
    x += (delta * xVel)
    y += (delta * yVel)
  }
}
~~~~~

>- Remainder **inherited** from `Point`

## The Class Spectrum in Scala: Classes

We have **also** automatically defined new **type** ...

~~~~~{.scala}
class Dot(val name: String, x0: Int, y0: Int) extends Point {
  def render(g: Graphics) {
    g.fillOval(x, y, xDim, yDim)
  }
 
  override def move(d: Dimension, delta: Int) {
    x += (delta * xVel)
    y += (delta * yVel)
  }
}
~~~~~

... with **name** `Dot`

>- and specified it is a **subtype** of `Point`

>- Called **Nominal** (by-name) subtyping

>- Can use `Dot` where `Point` is **expected**



## The Class Spectrum in Scala: Classes

Note the auxiliary constructor `this`

- Feeling lazy about supplying `x0`, `y0`?

~~~~~{.scala}
// Auxiliary constructor, invokes "real" constructor
def this(n: String) = 
  this(n, Rand(0, 100), Rand(0, 100))
~~~~~

## The Class Spectrum in Scala: Classes

### Lets create an **instance**

With the default constructor ...

~~~~~{.scala}
new Dot("p1", 50, 50) // Default constructor
~~~~~

... and with the auxiliary one

~~~~~{.scala}
new Dot("p2")       // Auxiliary constructor 
~~~~~


## QUIZ: Mutation Revisited

~~~~~{.scala}
class Dot(val name: String, x0: Int, y0: Int) extends Point {
  // Filled in by "constructor"
  var x     = x0 
  var y     = y0 
  def xDim  = 20
  def yDim  = 20
  ...
}
~~~~~

Are instances of `Dot` 

**A.** Mutable

**B.** Immutable

**C.** None of the above


## Recap: What is a Class?

Spectrum from Specification to Implementation

### 1. Interfaces

**Only** Specification of Types

e.g. `ticker`

### 2. Abstract Class

Specification + **Some** Concrete Implementations

e.g. `Point`

### 3. Class

Specification + **All** Concrete Implementations

e.g. `Dot`

## OK! Lets Run The Screensaver!

## So far: Objects + Classes + (Some) Inheritance

## How to get colored dots?


## Inheritance

**Extend** `Dot` with a notion of color

~~~~~{.scala}
class ColorDotV1(name: String, color: Color)
extends Dot(name) {
  override def render(g: Graphics) { 
    g.setColor(color) //"color" in scope from params
    super.render(g)
  }
}
~~~~~

### Note: `extends Dot(name)` 

- Pithy way of calling the (old) super-class constructor

- Passing it the parameter(s) of the (new) sub-class



## QUIZ: Inheritance

~~~~~{.scala}
class ColorDotV1(name: String, color: Color)
extends Dot(name) {
  override def render(g: Graphics) { 
    g.setColor(color) //"color" in scope from params
    super.render(g)
  }
}
~~~~~

What has `ColorDotV1` inherited ?

**A.** `render` from `Point` 

**B.** `move` from `Point`

**C.** `render` from `Dot`

**D.** `move` from `Dot`

**E.** All of the above

## QUIZ: Inheritance

Lets **extend** `Dot` with a notion of `color`

~~~~~{.scala}
class ColorDotV1(name: String, color: Color) 
extends Dot(name) {
  override def render(g: Graphics) { 
    g.setColor(color) //"color" in scope from params
    super.render(g)
  }
}
~~~~~

What does `super.render` refer to?

**A.** `render` in `Point` 

**B.** `render` in `Dot`

**C.** `render` in Sur`render`


## QUIZ: Inheritance

~~~~~{.scala}
class ColorDotV1(name: String, color: Color) 
extends Dot(name) {
  override def render(g: Graphics) { 
    g.setColor(color) //"color" in scope from params
    super.render(g)
  }
}
~~~~~

The new type `ColorDotV1` is a subtype of

**A.** `ticker` 

**B.** `Point` 

**C.** `Dot` 

**D.** Both `Point` and `Dot` 

**E.** Neither `Point` nor `Dot`

## Inheritance Enables Reuse

Get lots of **properties** from without any work!

<img src="../static/billionaire.jpg" width=300 align="middle"/> 

>- Only need to override or extend bits that are different...

## Lets make another shape

How about a `Box` ?

~~~~~{.scala}
class Box(name: String, h: Int, w: Int) extends Dot(name) {
  override def yDim = w 
  override def xDim = h

  override def render(g: Graphics) {
    g.fillRect(x, y, h, w)
  }
}
~~~~~

Get lots of stuff without any work!

- Get `move` (from `Dot`) **for free**!

- Get `collide` (from `Point`) **for free**!


## Lets make another shape

How about a `Box` ?

Lets check it out ...

~~~~~{.scala}
val points = List( ...
                 , new Box("p4", 20, 40)
                 )
~~~~~

## But wait a minute...

## Wait a minute ... beware of things you get **for free**

<img src="../static/HomerAngel.jpg" width=300 align="middle"/> 

>- Good Angel: Is a `Box` really a `Dot` ?
>- Evil Angel: But we're getting so much **reuse** !!
>- Good Angel: ...

## Lets make (yet) another shape

How about we **color** them `Box`es?

>- But how?

>- Inheritance? 

>- Lets see...

## Lets make (yet) another shape: ColorBox

Lets try extending `Box` ...

~~~~~{.scala}
class ColorBoxV1(name: String, color: Color, h: Int, w: Int) 
extends Box(name, h: Int, w: Int) {
  override def render(g: Graphics) {
    g.setColor(color) 
    super.render(g)
  }
}
~~~~~

... Yikes! We're repeating ourselves! 

>- `render` is **just** like `ColorDot.render` 

>- How can we reuse the above `render` ?

## Lets make (yet) another shape: ColorBox

No problem, just make `ColorBox` inherit from (extend) `ColorDot`.

Whats the problem?

**A.** Cannot extend `ColorDot`

**B.** Would have to duplicate `render` method from `Dot`

**C.** Don't fuss, **THERE IS NO PROBLEM!**

**D.** Would have to duplicate `render` method from `Box`

**E.** Would have to duplicate constructor from `Box`

## Problem

We bundled Colored-ness into `ColorDot` ...

... but color is **totally independent** of Shape!

How can we **free up** colored-ness from its chains?

<img src="../static/breaking-chain.jpg" height=200 align="middle"/> 

# Traits

## Traits

Describe object **behaviors** independent particular classes ...

... Can be **mixed** into any class to add that behavior to the class!

## Traits describe Object Behaviors Independently

~~~~~{.scala}
trait Colored extends Point {
  
  val color: Color  // Will be defined by mixin-target
  
  abstract override def render(g: Graphics) {
    g.setColor(color)     
    super.render(g) // Call render of mixin-target
  }
}
~~~~~

This exactly **specifies** and **implements** colored-ness ...

... without bundling it inside a particular class!

## Traits describe Object Behaviors Independently

~~~~~{.scala}
trait Colored extends Point {
  
  val color: Color  // Will be defined by mixin-target
  
  abstract override def render(g: Graphics) {
    g.setColor(color)     
    super.render(g) // Call render of mixin-target
  }
}
~~~~~

### Wait! Aren't traits just like Java interfaces?


## QUIZ: Traits describe Object Behaviors Independently

~~~~~{.scala}
trait Colored extends Point {
  val color: Color  // Will be defined by mixin-target
  abstract override def render(g: Graphics) {
    g.setColor(color)     
    super.render(g) // Call render of mixin-target
  }
}
~~~~~

Why do we write `extends Point`?

**A.** Good documentation, we don't *have* to write it

**B.** Only `Point` objects can have a `color` field

**C.** Only `Point` objects can have a `setColor` method

**D.** Both **B** and **C**

**E.** Only `Point` objects can have a `render` method

## Traits Can Be Mixed-Into Appropriate (Host) Classes

To use a trait, just **mixin** to an appropriate host class.

(e.g. subtype of `Point`)

~~~~~{.scala}
class ColorDot(name: String, val color: Color) 
  extends Dot(name) with Colored

class ColorBox(name: String, val color: Color, h: Int, w: Int) 
  extends Box(name, h, w) with Colored
~~~~~

Lets take the new classes for a spin!

## Traits: Recap

Describe object **behaviors** independent particular classes ...

... Can be **mixed** into any class to add that behavior to the class!

# Are traits different from **Multiple Inheritance**

## Are traits different from **Multiple Inheritance**

Why can't I do something like this:

~~~~~{.scala}
abstract class Point
class Dot extends Point {...}
class Colored extends Point {...}
~~~~~

and then 

~~~~~{.scala}
class ColoredDot extends Dot, Colored {...}
~~~~~

Wouldn't this solve the problem of reusing `Color` and `Dot` ?

>- Problem 1: Which parent do I pick method from?
>- Problem 2: Need to compose `render` from **both**


## Are traits different from **Multiple Inheritance**

The cunning thing about traits:

~~~~~{.scala}
trait Colored extends Point {
  
  val color: Color  // Will be defined by mixin-target
  
  abstract override def render(g: Graphics) {
    g.setColor(color)     
    super.render(g) // Call render of mixin-target
  }
}
~~~~~

>- **stacks** the new behavior

>- **on top of** existing behavior! (`super.render`)

>- independent of the host class!

>- So, color-a-box, color-a-dot, color-anything!


# Another Trait: Bouncing

## Another Trait: Bouncing

Lets add a notion of **gravity** to the objects...

~~~~~{.scala}
trait Bouncing extends Point {
  ... 
  abstract override def move(d: Dimension, delta: Int) {
    yVel += delta       
    shootUp()               // if ROTFL
    super.move(d, delta)    // preserve
  }
}
~~~~~

## Another Trait: Bouncing

Lets add a **gravity** behavior to the objects...

>- independent of shape, color, etc.

~~~~~{.scala}
trait Bouncing extends Point {
  ... 
  abstract override def move(d: Dimension, delta: Int) {
    yVel += delta       
    shootUp()               // if ROTFL
    super.move(d, delta)    // preserve
  }
}
~~~~~

### Note how new behavior stacked on top of old!

- Reuse old (horizontal) motion via `super.move`

## Another Trait: Bouncing

We can add bouncing behavior to **any** `Point` object

~~~~~{.scala}
class BouncingColorDot(name: String, val color: Color) 
  extends Dot(name) with Colored with Bouncing

class BouncingColorBox(name: String, val color: Color, h: Int, w: Int) 
  extends Box(name, h, w) with Colored with Bouncing
~~~~~

Or even directly **retro-actively** to the instance `object`

~~~~~{.scala}
new Dot("p2") with Bouncing
~~~~~

# Moral of the story?

## Moral of the story

Inheritance enables reuse 

**BUT**

Class(ical) inheritance **locks** reusable behaviors

Into **unrelated** classes (e.g. `ColorDotV1`)

In fact ...

# Our code can be cleaned up more...

## QUIZ: Our ScreenSaver can be cleaned up more...

There remains another accidental intertwining...

...behavior **locked inside** unrelated class.

Where?

**A.** `collide`

**B.** `move` 

**C.** `color`

**D.** `Dot`

**E.** `Box`



## Moral of the story

Inheritance enables reuse 

**BUT**

Class(ical) inheritance **locks** reusable behaviors

Into **unrelated** classes (e.g. `ColorDotV1`)

**SO**

Keep a sharp eye out for independent behaviors,

and **set them free** using **traits**.



