Sample run of chapter's interpreter examples
// In file traits/Philosophical.scala trait Philosophical { def philosophize() = { println("I consume memory, therefore I am!") } }
class Frog extends Philosophical { override def toString = "green" }
scala> val frog = new Frog frog: Frog = green scala> frog.philosophize() I consume memory, therefore I am!
scala> val phil: Philosophical = frog phil: Philosophical = green scala> phil.philosophize() I consume memory, therefore I am!
// In file traits/Ex1.scala class Animal class Frog extends Animal with Philosophical { override def toString = "green" }
// In file traits/Frog.scala class Animal trait HasLegs class Frog extends Animal with Philosophical with HasLegs { override def toString = "green" }
// In file traits/Ex2.scala class Animal class Frog extends Animal with Philosophical { override def toString = "green" override def philosophize() = { println("It ain't easy being " + toString + "!") } }
scala> val phrog: Philosophical = new Frog phrog: Philosophical = green scala> phrog.philosophize() It ain't easy being green!
// In file traits/Ex2.scala class Point(x: Int, y: Int)
trait NoPoint(x: Int, y: Int) // Does not compile
// In file traits/Ex2.scala trait CharSequence { def charAt(index: Int): Char def length: Int def subSequence(start: Int, end: Int): CharSequence def toString(): String }
// In file traits/Point.scala class Point(val x: Int, val y: Int) class Rectangle(val topLeft: Point, val bottomRight: Point) { def left = topLeft.x def right = bottomRight.x def width = right - left // and many more geometric methods... }
abstract class Component { def topLeft: Point def bottomRight: Point def left = topLeft.x def right = bottomRight.x def width = right - left // and many more geometric methods... }
// In file traits/Rectangular.scala trait Rectangular { def topLeft: Point def bottomRight: Point def left = topLeft.x def right = bottomRight.x def width = right - left // and many more geometric methods... }
abstract class Component extends Rectangular { // other methods... }
// In file traits/Rectangle.scala class Rectangle(val topLeft: Point, val bottomRight: Point) extends Rectangular { // other methods... }
scala> val rect = new Rectangle(new Point(1, 1), | new Point(10, 10)) rect: Rectangle = Rectangle@5f5da68c scala> rect.left res2: Int = 1 scala> rect.right res3: Int = 10 scala> rect.width res4: Int = 9
class Rational(n: Int, d: Int) { // ... def < (that: Rational) = this.numer * that.denom < that.numer * this.denom def > (that: Rational) = that < this def <= (that: Rational) = (this < that) || (this == that) def >= (that: Rational) = (this > that) || (this == that) }
// In file traits/Rational.scala class Rational(n: Int, d: Int) extends Ordered[Rational] { // ... def compare(that: Rational) = (this.numer * that.denom) - (that.numer * this.denom) }
scala> val half = new Rational(1, 2) half: Rational = 1/2 scala> val third = new Rational(1, 3) third: Rational = 1/3 scala> half < third res5: Boolean = false scala> half > third res6: Boolean = true
// In file traits/Ex2.scala trait Ordered[T] { def compare(that: T): Int def <(that: T): Boolean = (this compare that) < 0 def >(that: T): Boolean = (this compare that) > 0 def <=(that: T): Boolean = (this compare that) <= 0 def >=(that: T): Boolean = (this compare that) >= 0 }
// In file traits/IntQueue.scala abstract class IntQueue { def get(): Int def put(x: Int): Unit }
// In file traits/BasicIntQueue.scala import scala.collection.mutable.ArrayBuffer class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer[Int] def get() = buf.remove(0) def put(x: Int) = { buf += x } }
scala> val queue = new BasicIntQueue queue: BasicIntQueue = BasicIntQueue@23164256 scala> queue.put(10) scala> queue.put(20) scala> queue.get() res9: Int = 10 scala> queue.get() res10: Int = 20
// In file traits/Ex2.scala trait Doubling extends IntQueue { abstract override def put(x: Int) = { super.put(2 * x) } }
scala> class MyQueue extends BasicIntQueue with Doubling defined class MyQueue scala> val queue = new MyQueue queue: MyQueue = MyQueue@44bbf788 scala> queue.put(10) scala> queue.get() res12: Int = 20
scala> val queue = new BasicIntQueue with Doubling queue: BasicIntQueue with Doubling = $anon$1@141f05bf scala> queue.put(10) scala> queue.get() res14: Int = 20
// In file traits/Incrementing.scala trait Incrementing extends IntQueue { abstract override def put(x: Int) = { super.put(x + 1) } } trait Filtering extends IntQueue { abstract override def put(x: Int) = { if (x >= 0) super.put(x) } }
scala> val queue = (new BasicIntQueue | with Incrementing with Filtering) queue: BasicIntQueue with Incrementing with Filtering... scala> queue.put(-1); queue.put(0); queue.put(1) scala> queue.get() res16: Int = 1
scala> queue.get() res17: Int = 2
scala> val queue = (new BasicIntQueue | with Filtering with Incrementing) queue: BasicIntQueue with Filtering with Incrementing... scala> queue.put(-1); queue.put(0); queue.put(1) scala> queue.get() res19: Int = 0 scala> queue.get() res20: Int = 1 scala> queue.get() res21: Int = 2
// In file traits/Ex2.scala // Multiple inheritance thought experiment val q = new BasicIntQueue with Incrementing with Doubling q.put(42) // which put would be called?
// Multiple inheritance thought experiment trait MyQueue extends BasicIntQueue with Incrementing with Doubling { def put(x: Int) = { Incrementing.super.put(x) // (Not real Scala) Doubling.super.put(x) } }
// In file traits/Ex3.scala class Animal trait Furry extends Animal trait HasLegs extends Animal trait FourLegged extends HasLegs class Cat extends Animal with Furry with FourLegged
For more information about Programming in Scala, Fourth Edition (the "Stairway Book"), please visit: http://www.artima.com/shop/programming_in_scala_4ed and: |
Copyright © 2007-2019 Artima, Inc. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. |