2012-01-05 32 views
8

Tôi có một chút nhầm lẫn về việc truy cập các lớp bên trong riêng tư của một đối tượng với các phương thức của cùng một đối tượng. Đây là mã của excercise của tôi từ trình trong Scala (trang 245-246):Scala đối tượng phạm vi riêng với các lớp bên trong và phương pháp

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) 

} 

Mã này cũng giống như trong cuốn sách, nhưng trình biên dịch phàn nàn về ba phương pháp def elem() tại botton của đối tượng phần tử . Các lỗi nói:

tin lớp ArrayElement thoát phạm vi xác định của nó như là một phần của loại pis.Code_c10s02_CompositionAndInheritance.Element.ArrayElement

Tuy nhiên, nếu tôi loại bỏ các modifier private từ các lớp bên trong, mọi thứ trở nên được. Đây không phải là giải pháp, có vẻ như phần này của cuốn sách về cơ bản là về việc tư nhân hoá các lớp bên trong một đối tượng. Sai lầm của tôi ở đây là gì?

Trả lời

13

Vì một số lý do, thay vào đó sẽ không biên dịch hơn là suy ra một loại ít cụ thể hơn nhưng công khai hơn. Khai báo các phương thức elem với kiểu trả về.

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

Tôi đã nghĩ rằng một số phần tiếp theo của câu hỏi này sau đó: tại sao loại trả về phải là 'Element' trong mỗi trường hợp chứ không phải kiểu cụ thể được sử dụng để tạo Đối tượng? Tôi nghĩ rằng điều này là bằng cách nào đó liên quan đến sự riêng tư/publicy nhưng tôi không thể có được điểm ... Có ý nghĩa thực sự cho nó hoặc là nó một trình biên dịch quirk? – noncom

+0

Loại là riêng tư, vì vậy nó không thể nhìn thấy bên ngoài phạm vi xác định của nó. Nghe có vẻ như những gì bạn thực sự muốn là một nhà xây dựng tư nhân. – extempore

Các vấn đề liên quan