Scala アクセス修飾子


Scala のアクセス修飾子は、プライベート、プロテクト、パブリックなど、基本的に Java のアクセス修飾子と同じです。

アクセス修飾子が指定されていない場合、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 では、保護されたメンバーへのアクセスは Java よりも厳格です。これは、保護されたメンバーへのアクセスが、そのメンバーが定義されているクラスのサブクラス内でのみ許可されるためです。 Java では、protected キーワードで変更されたメンバーには、そのメンバーを定義するクラスのサブクラスだけでなく、同じパッケージ内の他のクラスからもアクセスできます。

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

上記の例では、f は Super で保護されていると宣言されており、Sub は Super のサブクラスであるため、Sub クラスは f に問題なくアクセスできます。対照的に、Other は Super を継承していないため、Other の f へのアクセスは許可されません。 Other と Sub は同じパッケージ内にあるため、後者は Java でも認識されます。


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] と書かれた場合、「このメンバーは、[...] のクラス、または [...] のパッケージ内のクラスとそのコンパニオン オブジェクトを除くすべてのクラスに対してプライベートです。

This Thisこの手法は、複数のパッケージにまたがる大規模なプロジェクトで非常に役立ちます。これにより、プロジェクトの複数のサブパッケージには表示されるが、プロジェクト外のクライアントには決して表示されないものを定義できます。

package bobsrocckets{
    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.これは、このクラスが bobsrockets パッケージに含まれるすべてのクラスとオブジェクトに表示されることを意味します。たとえば、Vehicle オブジェクトが起動パッケージに含まれているため、Vehicle オブジェクトから Navigator へのアクセスが許可されます。逆に、パッケージ bobsrockets の外にあるすべてのコードは Navigator クラス

にアクセスできません。