English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Scala 접근 지정자

Scala 접근수준은 Java와 유사합니다. private, protected, public으로 구분됩니다.

접근수준을 지정하지 않으면, Scala 객체의 접근 수준은 기본적으로 public입니다.

Scala의 private 제한자는 Java보다 더 엄격합니다. 내부 클래스의 경우, 외부 클래스는 내부 클래스의 private 멤버에 접근할 수 없습니다.

private(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에 대한 접근이 허용되지 않습니다. 그리고 이는 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입니다."라고 읽습니다.

이 기술은 여러 패키지를 가진 대형 프로젝트에서 매우 유용하며, 프로젝트의 여러 서브 패키지에서 볼 수 있지만 프로젝트 외부의 고객에게는 항상 볼 수 없는 것들을 정의할 수 있게 합니다.

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에 대한 접근은 Navigator 클래스가 launch 패키지에 포함되어 있기 때문에 허용됩니다. launch 패키지는 bobsrockets 패키지에 포함되어 있으며, 반대로 bobsrockets 패키지 밖의 모든 코드는 Navigator 클래스에 접근할 수 없습니다.