클래스와 오브젝트#1
visibility modifier(가시성 변경자)
코틀린에서 클래스 선언시 별다른 modifier를 붙이지 않는다면 기본적으로 public으로 정의된다.
코틀린에서는 자바에서와 같은 패키지 전용 접근 제어자는 없고, 그에 대한 대안으로 internal
을 도입하였다.
internal은 “같은 모듈 내부에서만 접근 가능
“하며, 여기서 모듈
은 한 번에
한꺼번에 컴파일 되는 코틀린 파일들을 의미한다.
private 는 같은 파일에서만 접근 가능
하다는 것을 의미한다.
modifier | 클래스 멤버 | 최상위 선언 |
---|---|---|
public(기본) | 모든 곳에서 볼수 있다. | 모든 곳에서 볼수 있다. |
internal | 같은 모듈 안에서만 볼 수 있다. | 같은 모듈 안에서만 볼 수 있다. |
protected | 하위 클래스 안에서만 볼 수 있다. | (최상위 선언에 적요할 수 없음) |
private | 같은 클래스 안에서만 볼 수 있다. | 같은 파일 안에서만 볼 수 있다. |
아래 TalkativeButton 메소드는 모두 syntax가 발생하는데, 하나씩 확인해 보자.
internal open class TalkativeButton : MyInterface {
private fun yell() = println("Hey")
protected fun whisper() = println("Let's talk!")
}
fun TalkativeButton.giveSpeech() { //Error--- (1)
yell() //Error--- (2)
whisper() //Error--- (3)
}
- (1) public인 멤버가 자신의 “internal”타입인 “TalkativeButton”을 노출함.
- (2) yell함수는 private이므로 TalkativeButton의 내에서만 접근 가능하다.
-
(3) TalkativeButton의 하위 클래스가 아니므로 접근 불가
-
컴파일된 코틀린의 public, protected, private 변경자는 컴파일된 자바 바이트코드 안에서도 그대로 유지 된다.
internal 변경자의 경우는, 자바에 딱 맞는 가시성이 없어 바이트 코드상에서는 public이 된다.
이런 차이 때문에 코틀린에서는 접근할 수 없는 대상을 자바에서 접근할 수 있는 경우가 생긴다. - 코틀린 컴파일러는 internal 멤버의 이름을 변경하는데, 이는 한 모듈에 속한 어떤 클래스를 모듈 밖에서 상속한
경우 그 하위 클래스 내부의 메소드 이름이 우연히 상위 클래스의 internal 메소드와 같아져서 내부 메소드를 오버라이드하는
경우를 방지하고, 실수로 internal 클래스를 보듈 외부에서 사용하는 일을 막기 위함이다.
내부 클래스
자바와는 달리 코틀린에서는 내부에 선언된 클래스에서 명시적으로 요청하지 않는 한 바깥쪽 클래스 인스턴스에 대한 접근 권한이 없다.
이는 자바의static
중첩 클래스와 동일하다.
먼저 java에서의 InnerClass(내부 클래스)와 NestedClass(중첩 클래스)를 살펴 보자.
코틀린에서 내부 클래스에 inner
를 붙이지 않으면 자바 static중첩 클래스로 정의 된다.
자바와 코틀린의 충첩 클래스와 내부 클래스의 관계를 정리하면 다음과 같다.
클래스 B안에 정의된 클래스 A | 자바에서는 | 코틀린에서는 |
---|---|---|
중첩 클래스 | static class A | class A |
내부 클래스 | class A | inner class A |