天天看點

Scala 通路修飾符

Scala 通路修飾符基本和Java的一樣,分别有:private,protected,public。

如果沒有指定通路修飾符,預設情況下,Scala 對象的通路級别都是 public。

Scala 中的 private 限定符,比 Java 更嚴格,在嵌套類情況下,外層類甚至不能通路被嵌套類的私有成員。

用 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 中允許這兩種通路,因為它允許外部類通路内部類的私有成員。

在 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 在同一包裡。

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

class Outer {

   class Inner {

      def f() { println("f") }

      class InnerMost {

         f() // 正确

      }

   }

   (new Inner).f() // 正确因為 f() 是 public

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

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

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

package bobsrockets{

    package navigation{

        private[bobsrockets] class Navigator{

         protected[navigation] def useStarChart(){}

         class LegOfJourney{

             private[Navigator] val distance = 100

             }

            private[this] var speed = 200

            }

        package launch{

        import navigation._

        object Vehicle{

        private[launch] val guide = new Navigator

上述例子中,類 Navigator 被标記為 private[bobsrockets] 就是說這個類對包含在 bobsrockets 包裡的所有的類和對象可見。

比如說,從 Vehicle 對象裡對 Navigator 的通路是被允許的,因為對象 Vehicle 包含在包 launch 中,而 launch 包在 bobsrockets 中,相反,所有在包 bobsrockets 之外的代碼都不能通路類 Navigator。