캡슐화(encapsulation)란
- 클래스를 작성할 때 외부에서 숨겨야 하는 속성이나 기능
- 가시성 지시자(visibility modifiers)를 통해 외부 접근 범위를 결정할 수 있다.
- private: 이 지시자가 붙은 요소는 외부에서 접근 불가
- public: 이 요소는 어디서든 접근이 가능 (기본값)
- protected: 외부에서 접근할 수 없으나 하위 상속 요소에서는 가능
- internal: 같은 정의의 모듈 내부에서 접근 가능
public, private 코드 예시
package com.example.demo.inherit
private class PrivateTest {
private var i = 1
private fun privateFunc() {
i += 1
println(i)
}
fun access() { // public
privateFunc()
}
}
class otherClass {
// val pc = PrivateTest() // 공개 생성 불가
fun test() {
val pc = PrivateTest()
pc.access()
}
}
fun main() {
val pc = PrivateTest() // 최상의 함수에서 Private 객체생성이 가능
// pc.i = 3 // 프로퍼티 i는 해당 클래스 내에서만 접근 가능
// pc.privateFunc() // 마찬가지로 접근 불가
pc.access() // public으로 선언한 함수에 private을 호출한 뒤 public으로 선언한 함수를 호출해 사용함
}
fun topFunction() {
val pc = PrivateTest() // 사용자가 만든 top level 이기때문에 마찬가지로 사용이 가능하다.
}
protected 사용 예시 (상속관계에서의 지시자)
package com.example.demo.inherit
open class Base {
protected var i = 1
protected fun protectecdFunc() {
i += 1
}
fun access() {
protectecdFunc() // public으로 만들었을 땐 접근이 가능하다.
}
}
class Derived : Base() {
var j = 1 + i
fun derivedFunc(): Int {
protectecdFunc()
return i
}
}
class Other {
fun other() {
val base = Base()
// base.i = 3 // 상속관계가 아니기 때문에 i에 접근할 수 없다.
}
}
fun main() {
val base = Base() // 최상위 함수기때문에 호출 가능
// base.i // 최상위 함수여도 프로퍼티엔 접근할 수 없다.
// base.protectedFunc() // 최상위 함수여도 메서드엔 접근할 수 없다.
base.access() // public으로 만든 함수기 때문에 호출이 가능
val derived = Derived() // public이기에 접근가능
derived.j = 3
}
internal 사용 예시 (모듈에서의 지시자)
package com.example.demo.inherit
internal class InternalClass {
internal var i = 1
internal fun icFunc() {
}
fun access() {
icFunc()
}
}
class Other1 {
internal val ic = InternalClass()
fun test() {
ic.i // 접근허용
ic.icFunc() // 접근허용
}
}
fun main() {
val mic = InternalClass()
mic.i // 접근허용
mic.icFunc() // 접근허용
}