[Scala]protectedの挙動
protectedの挙動ですが、まず
scalaでは、class とか object のメンバーはデフォルトではすべてパブリックとして定義されます
[scala]object PublicObject {
val publicVal
var publicVar
def publicMethod = 1
}[/scala]
この例では、3つのメンバーは全部publicとして定義される
privateとprotectedは、Javaに良く似ています。
privateはJavaとほぼ同等の動きですが、protectedは劇的に異なります。
一つ目の違いは、protectedは2つの形式を持つことが出来ます。
protectedとprotected[foo]
※fooはclass、package、objectなど
二つ目の違いは、パラメータなしのprotectedは自身とサブクラスからのみ参照可能
[scala]scala> class Class1 {
| protected def pMethod = "protected"
| }
defined class Class1
scala> class Class2 {
// Class2はClass1のサブクラスでは無いので、pMethod にはアクセス出来ません。
| new Class1().pMethod
| }
<console>:6: error: method pMethod cannot be accessed in Class1
new Class1().pMethod
^
scala> class Class3 extends Class1 {
// ここがJavaと違うところで、pMethodにはアクセス出来ません。
| new Class1().pMethod
| }
<console>:6: error: method pMethod cannot be accessed in Class1
new Class1().pMethod
^
scala> class Class3 extends Class1 {
// pMethodにアクセス出来ます。
| pMethod
| }
defined class Class3[/scala]
パラメータありのprotectedの場合
パラメータに指定されたクラスからは参照できるようになります
[scala]scala> class Class1 {
// protected[Class1] は、privateと同等
| protected[Class1] def method() = println("hi")
| method()
| }
defined class Class1
scala> new Class1()
hi
res0: Class1 = Class1@dc44a6d
// このmethodは、Class1からのみアクセスが出来ます。
scala> class Class2 extends Class1 { method() }
<console>:5: error: not found: value method
class Class2 extends Class1 { method() }
^
scala> object Module {
| object Inner1 {
| protected[Inner1] def innerMethod = println("hi")
| protected[Module] def moduleMethod = println("moduleMethod")
|
| object InnerInner {
| // InnerInner は Inner1 の中にあるので アクセス可能
| def callInner = innerMethod
| }
| }
| // moduleMethod は protected[Module] なので、Module内からはアクセス出来ます。
| def callModuleMethod = Inner1.moduleMethod
|
| object Inner2 {
| // Inner1.moduleMethod は protected[Module] ですが、Inner2の中なので、moduleMethodはアクセス可能です。
| def callModuleMethod = Inner1.moduleMethod
| }
| }
defined module Module
scala> Module.callModuleMethod
moduleMethod
scala> Module.Inner1.InnerInner.callInner
hi
scala> Module.Inner1.innerMethod
<console>:6: error: method innerMethod cannot be accessed in object Module.Inner1
Module.Inner1.innerMethod
^
scala> Module.Inner1.moduleMethod
<console>:6: error: method moduleMethod cannot be accessed in object Module.Inner1
Module.Inner1.moduleMethod[/scala]