Scala 存取修飾符


Scala 存取修飾符基本上和Java的一樣,分別有:private,protected,public。

如果沒有指定存取修飾符符,預設情況下,Scala物件的存取等級都是 public。

Scala 中的 private 限定符,比 Java 更嚴格,在巢狀類別情況下,外層類別甚至無法存取被巢狀類別的私有成員。


私有(Private)成員

用private關鍵字修飾,帶有此標記的成員僅在包含了成員定義的類別或物件內部可見,同樣的規則也適用內部類別。

class Outer{
    class Inner{
    private def f(){println("f")}
    class InnerMost{
        f() // 正确
        }
    }
    (new Inner).f() //错误
}

(new Inner).f( ) 存取不合法是因為 f 在 Inner 中被宣告為 private,而存取不在類別Inner之內。

但在 InnerMost 裡訪問f就沒有問題的,因為這個訪問包含在 Inner 類別之內。

Java中允許這兩種訪問,因為它允許外部類別存取內部類別的私有成員。


保護(Protected)成員

在 scala 中,對保護(Protected)成員的存取比 java 更嚴格一些。因為它只允許保護成員在定義了該成員的類別的子類別中被存取。而在java中,用protected關鍵字修飾的成員,除了定義了該成員的類別的子類別可以訪問,同一個套件裡的其他類別也可以進行訪問。

package p{
class Super{
    protected def f() {println("f")}
    }
	class Sub extends Super{
	    f()
	}
	class Other{
		(new Super).f() //错误
	}
}

上例中,Sub 類別對 f 的存取沒有問題,因為 f 在 Super 中被宣告為 protected,而 Sub 是 Super 的子類別。相反,Other 對 f 的存取不被允許,因為 other 沒有繼承自 Super。而後者在 java 裡同樣被認可,因為 Other 與 Sub 在同一包裡。


公(Public)成員

Scala中,如果沒有指定任何的修飾符,則預設為 public。這樣的成員在任何地方都可以被訪問。

class Outer {
   class Inner {
      def f() { println("f") }
      class InnerMost {
         f() // 正确
      }
   }
   (new Inner).f() // 正确因为 f() 是 public
}

作用域保護

Scala中,存取修飾符可以透過使用限定詞強調。格式為:

private[x] 

或 

protected[x]

這裡的x指涉某個所屬的套件、類別或單例物件。如果寫成private[x],讀作"這個成員除了對[…]中的類別或[…]中的包中的類別及它們的伴生對像可見外,對其它所有類別都是private。

這種技巧在橫跨了若干包的大型專案中非常有用,它允許你定義一些在你專案的若干子包中可見但對於專案外部的客戶卻始終不可見的東西。

上述例子中,類別Navigator被標記為private[bobsrockets]就是說這個類別對包含在bobsrockets包裡的所有的類別和物件可見。存取是被允許的,因為物件Vehicle包含在套件launch中,而launch套件在bobsrockets中,相反,所有在套件bobsrockets之外的程式碼都不能存取類別Navigator。