2012-01-05 35 views
8

我對使用同一對象的方法訪問對象的私有內部類有點混淆。這裏是我的鍛鍊; Tibial從編程Scala中的代碼(頁245-246):斯卡拉對象與內部類和方法的私人範圍

import Element.elem 

abstract class Element { 
    def contents: Array[String] 
    def height = contents.length 
    def width = if(height == 0) 0 else contents(0).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" 
} 


object Element { 

    private class ArrayElement (
      val contents: Array[String] 
    ) extends Element 

    private class LineElement (s: String) extends ArrayElement(Array(s)) { 
      override def width = s.length 
      override def height = 1 
    } 

    private class UniformElement (
      val ch: Character, 
      override val width: Int, 
      override val height: Int 
    ) extends Element { 
      private val line = ch.toString * width 
      def contents = Array.fill(height)(line) 
    } 

    def elem(ss: Array[String]) = new ArrayElement(ss) 
    def elem(s: String) = new LineElement(s) 
    def elem(ch: Character, w: Int, h: Int) = new UniformElement(ch, w, h) 

} 

的代碼是一樣的書,但是編譯器抱怨在Element對象的鈕三個def elem()方法。錯誤說:

私有類ArrayElement逃脫它的定義範圍爲 類型的一部分pis.Code_c10s02_CompositionAndInheritance.Element.ArrayElement

但是,如果我從內部類中刪除private修飾,一切都變得好。這不應該是解決方案,看起來本書的這一部分主要是關於對象內部的類的私有化。我在這裏犯了什麼錯誤?

回答

13

出於某種原因,它寧願編譯失敗,而不是推斷一個不太具體但公開的類型。用返回類型聲明elem方法。

def elem(ss: Array[String]): Element    = new ArrayElement(ss) 
def elem(s: String): Element      = new LineElement(s) 
def elem(ch: Character, w: Int, h: Int): Element = new UniformElement(ch, w, h) 
+0

我已經想到了一些更多的,有來此問題的下一個部分,那麼:爲何返回類型必須是'Element'在每種情況下,而不是具體類型,該方法被用於創建對象?我認爲這與隱私/宣傳有某種關係,但我不明白這一點......是否有任何真正的意義或它是編譯器的怪癖? – noncom 2012-01-06 09:07:07

+0

該類型是私有的,因此它在其定義範圍之外是不可見的。這聽起來像你真正想要的是一個私人構造函數。 – extempore 2012-01-07 07:35:33