Sample run of chapter's interpreter examples
elem(s: String): Element
// In file composition-and-inheritance/LayoutElement.scala val column1 = elem("hello") above elem("***") val column2 = elem("***") above elem("world") column1 beside column2
hello *** *** world
abstract class Element { def contents: Array[String] }
abstract class Element ...
scala> new Element <console>:5: error: class Element is abstract; cannot be instantiated new Element ^
// In file composition-and-inheritance/Ex3.scala abstract class Element { def contents: Array[String] def height: Int = contents.length def width: Int = if (height == 0) 0 else contents(0).length }
def width(): Int
def width: Int
// In file composition-and-inheritance/Ex2.scala abstract class Element { def contents: Array[String] val height = contents.length val width = if (height == 0) 0 else contents(0).length }
// In file composition-and-inheritance/Ex2.scala Array(1, 2, 3).toString "abc".length
// In file composition-and-inheritance/Ex2.scala "hello".length // no () because no side-effect println() // better to not drop the ()
// In file composition-and-inheritance/Ex11.scala class ArrayElement(conts: Array[String]) extends Element { def contents: Array[String] = conts }
... extends Element ...
scala> val ae = new ArrayElement(Array("hello", "world")) ae: ArrayElement = ArrayElement@39274bf7 scala> ae.width res0: Int = 5
// In file composition-and-inheritance/Ex2.scala val e: Element = new ArrayElement(Array("hello"))
// In file composition-and-inheritance/Ex3.scala class ArrayElement(conts: Array[String]) extends Element { val contents: Array[String] = conts }
// This is Java class CompilesFine { private int f = 0; public int f() { return 1; } }
// In file composition-and-inheritance/Ex4.scala.err class WontCompile { private var f = 0 // Won't compile, because a field def f = 1 // and method have the same name }
// In file composition-and-inheritance/Ex6.scala class ArrayElement( val contents: Array[String] ) extends Element
class ArrayElement(x123: Array[String]) extends Element { val contents: Array[String] = x123 }
// In file composition-and-inheritance/Ex8.scala class Cat { val dangerous = false } class Tiger( override val dangerous: Boolean, private var age: Int ) extends Cat
// In file composition-and-inheritance/Ex8.scala class Tiger(param1: Boolean, param2: Int) extends Cat { override val dangerous = param1 private var age = param2 }
// In file composition-and-inheritance/Ex12.scala class LineElement(s: String) extends ArrayElement(Array(s)) { override def width = s.length override def height = 1 }
... extends ArrayElement(Array(s)) ...
$ scalac LineElement.scala .../LineElement.scala:50: error: method hight overrides nothing override def hight = 1 ^
def hidden(): Boolean
.../Shapes.scala:6: error: error overriding method hidden in class Shape of type ()Boolean; method hidden needs `override' modifier def hidden(): Boolean = ^
// In file composition-and-inheritance/Ex12.scala class UniformElement( ch: Char, override val width: Int, override val height: Int ) extends Element { private val line = ch.toString * width def contents = Array.fill(height)(line) }
// In file composition-and-inheritance/Ex9.scala val e1: Element = new ArrayElement(Array("hello", "world")) val ae: ArrayElement = new LineElement("hello") val e2: Element = ae val e3: Element = new UniformElement('x', 2, 3)
abstract class Element { def demo() = { println("Element's implementation invoked") } } class ArrayElement extends Element { override def demo() = { println("ArrayElement's implementation invoked") } } class LineElement extends ArrayElement { override def demo() = { println("LineElement's implementation invoked") } } // UniformElement inherits Element's demo class UniformElement extends Element
def invokeDemo(e: Element) = { e.demo() }
scala> invokeDemo(new ArrayElement) ArrayElement's implementation invoked
scala> invokeDemo(new LineElement) LineElement's implementation invoked
scala> invokeDemo(new UniformElement) Element's implementation invoked
class ArrayElement extends Element { final override def demo() = { println("ArrayElement's implementation invoked") } }
elem.scala:18: error: error overriding method demo in class ArrayElement of type ()Unit; method demo cannot override final member override def demo() = { ^
final class ArrayElement extends Element { override def demo() = { println("ArrayElement's implementation invoked") } }
elem.scala: 18: error: illegal inheritance from final class ArrayElement class LineElement extends ArrayElement { ^
// In file composition-and-inheritance/Ex11.scala class LineElement(s: String) extends Element { val contents = Array(s) override def width = s.length override def height = 1 }
// In file composition-and-inheritance/Ex10.scala def above(that: Element): Element = new ArrayElement(this.contents ++ that.contents)
// In file composition-and-inheritance/Ex10.scala def beside(that: Element): Element = { val contents = new Array[String](this.contents.length) for (i <- 0 until this.contents.length) contents(i) = this.contents(i) + that.contents(i) new ArrayElement(contents) }
// In file composition-and-inheritance/Ex10.scala new ArrayElement( for ( (line1, line2) <- this.contents zip that.contents ) yield line1 + line2 )
// In file composition-and-inheritance/Ex10.scala Array(1, 2, 3) zip Array("a", "b")
// In file composition-and-inheritance/Ex10.scala Array((1, "a"), (2, "b"))
// In file composition-and-inheritance/Ex10.scala override def toString = contents mkString "\n"
// In file composition-and-inheritance/Ex11.scala abstract class Element { def contents: Array[String] def width: Int = if (height == 0) 0 else contents(0).length def height: Int = contents.length def above(that: Element): Element = new ArrayElement(this.contents ++ that.contents) def beside(that: Element): Element = new ArrayElement( for ( (line1, line2) <- this.contents zip that.contents ) yield line1 + line2 ) override def toString = contents mkString "\n" }
// In file composition-and-inheritance/Ex12.scala object Element { def elem(contents: Array[String]): Element = new ArrayElement(contents) def elem(chr: Char, width: Int, height: Int): Element = new UniformElement(chr, width, height) def elem(line: String): Element = new LineElement(line) }
// In file composition-and-inheritance/Ex12.scala import Element.elem abstract class Element { def contents: Array[String] def width: Int = if (height == 0) 0 else contents(0).length def height: Int = contents.length def above(that: Element): Element = elem(this.contents ++ that.contents) def beside(that: Element): Element = elem( for ( (line1, line2) <- this.contents zip that.contents ) yield line1 + line2 ) override def toString = contents mkString "\n" }
new ArrayElement(Array("hello")) above new ArrayElement(Array("world!"))
new ArrayElement(Array("one", "two")) beside new ArrayElement(Array("one"))
// In file composition-and-inheritance/LayoutElement.scala object Element { private class ArrayElement( val contents: Array[String] ) extends Element private class LineElement(s: String) extends Element { val contents = Array(s) override def width = s.length override def height = 1 } private class UniformElement( ch: Char, override val width: Int, override val height: Int ) extends Element { private val line = ch.toString * width def contents = Array.fill(height)(line) } def elem(contents: Array[String]): Element = new ArrayElement(contents) def elem(chr: Char, width: Int, height: Int): Element = new UniformElement(chr, width, height) def elem(line: String): Element = new LineElement(line) }
// In file composition-and-inheritance/LayoutElement.scala import Element.elem abstract class Element { def contents: Array[String] def width: Int = contents(0).length def height: Int = contents.length def above(that: Element): Element = { val this1 = this widen that.width val that1 = that widen this.width elem(this1.contents ++ that1.contents) } def beside(that: Element): Element = { val this1 = this heighten that.height val that1 = that heighten this.height elem( for ((line1, line2) <- this1.contents zip that1.contents) yield line1 + line2) } def widen(w: Int): Element = if (w <= width) this else { val left = elem(' ', (w - width) / 2, height) val right = elem(' ', w - width - left.width, height) left beside this beside right } def heighten(h: Int): Element = if (h <= height) this else { val top = elem(' ', width, (h - height) / 2) val bot = elem(' ', width, h - height - top.height) top above this above bot } override def toString = contents mkString "\n" }
// In file composition-and-inheritance/Spiral.scala import Element.elem object Spiral { val space = elem(" ") val corner = elem("+") def spiral(nEdges: Int, direction: Int): Element = { if (nEdges == 1) elem("+") else { val sp = spiral(nEdges - 1, (direction + 3) % 4) def verticalBar = elem('|', 1, sp.height) def horizontalBar = elem('-', sp.width, 1) if (direction == 0) (corner beside horizontalBar) above (sp beside space) else if (direction == 1) (sp above space) beside (corner above verticalBar) else if (direction == 2) (space beside sp) above (horizontalBar beside corner) else (verticalBar above corner) beside (space above sp) } } def main(args: Array[String]) = { val nSides = args(0).toInt println(spiral(nSides, 0)) } }
$ scala Spiral 6 $ scala Spiral 11 $ scala Spiral 17 +----- +---------- +---------------- | | | | +-+ | +------+ | +------------+ | + | | | | | | | | | | | +--+ | | | +--------+ | +---+ | | | | | | | | | | | | ++ | | | | | +----+ | | | | | | | | | | | | | | +----+ | | | | | ++ | | | | | | | | | | | | | +--------+ | | | +--+ | | | | | | | | | | | +------+ | | | | | | | +----------+ | | | +--------------+
For more information about Programming in Scala, Third Edition (the "Stairway Book"), please visit: http://www.artima.com/shop/programming_in_scala_3ed and: |
Copyright © 2007-2016 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. |