++ 캡슐화(encapsulation) ++
- 클래스를 작성할 때 외부에서 숨겨야 하는 속성이나 기능
- 가시성 지시자(visibility modifiers)를 통해 외부 접근 범위를 결정할 수 있음
- private: 이 지시자가 붙은 요소는 외부에서 접근할 수 없음
- public: 이 요소는 어디서든 접근이 가능 (기본값)
- protected: 외부에서 접근할 수 없으나 하위 상속 요소에서는 가능
- internal: 같은 정의의 모듈 내부에서는 접근이 가능
접근 제한자 | 최상위에서 사용할 때 | 클래스 멤버에서 사용할 때 |
public | 모든 파일에서 가능 | 모든 클래스에서 가능 |
internal | 같은 모듈 내에서 가능 | 같은 모듈 내에서 가능 |
protected | 사용 불가 | 상속 관계의 하위 클래스에서만 가능 |
private | 파일 내부에서만 사용 | 클래스 내부에서만 |
package com.example.pp151
private class PrivateClass {
private var i = 1
private fun privateFunc() {
i += 1 // 접근 허용
}
fun access() {
privateFunc() // 접근 허용
}
}
class OtherClass {
// val opc = PrivateClass() // 불가능 - 프로퍼티인 opc는 private이 되어야 한다.
fun test() {
val pc = PrivateClass() // 생성 가능
}
}
fun main() {
val pc = PrivateClass() // 생성 가능
// pc.i // 접근 불가
// pc.privateFunc() // 접근 불가
}
fun TopFunction() {
val tpc = PrivateClass() // 객체 생성 가능
}
private 가시성 테스트 예제
package com.example.pp152
open class Base { // 최상위 선언 클래스에는 protected를 사용할 수 없다.
protected var i = 1
protected fun protectedFunc() {
i += 1 // 접근 허용
}
fun access() {
protectedFunc() // 접근 허용
}
protected class Nested // 내부 클래스에는 지시자 허용
}
class Derived : Base() {
fun test(base: Base): Int {
protectedFunc() // Base 클래스의 메서드 접근 가능
return i // Base 클래스의 프로퍼티 접근 가능
}
}
fun main() {
val base = Base() // 생성 가능
base.i // 접근 불가
base.protectedFunc() // 접근 불가
base.access() // 접근 가능
}
protected 가시성 테스트 예제
package com.example.pp154
internal class InternalClass {
internal var i = 1
internal fun icFunc() {
i += 1 // 접근 허용
println(i)
}
fun access() {
icFunc() // 접근 허용
}
}
class Other {
internal val ic = InternalClass() // 프로퍼티 지정 시 internal로 맞춰야 한다.
fun test() {
println(ic.i) // 접근 허용
println(ic.icFunc()) // 접근 허용
}
}
fun main() {
val mic = InternalClass() // 생성 가능
mic.i // 접근 허용
mic.icFunc() // 접근 허용
val other = Other()
other.test()
}
internal 가시성 테스트 예제
UML
- : public
# : private + 상속 (같은 클래스 내에서 사용 가능), 상속하는 Derived에서 가능
~ : default, internal과 거의 같다.
+ : public
package com.example.pp156
open class Base {
// 이 클래스에서는 a, b, c, d, e 접근 가능
private val a = 1
protected open val b = 2
internal val c = 3
val d = 4 // 가시성 지시자 기본값은 public
protected class Nested {
// 이 클래스에서는 a, b, c, d, e, f 접근 가능
public val e: Int = 5 // public 생략 가능
private val f: Int = 6
}
}
class Derived: Base() {
// 이 클래스에서는 b, c, d, e 접근 가능 - a는 접근 불가
override val b = 5 // Base의 'b'는 오버라이딩됨. - 상위와 같은 protected 지시자
}
class Other(base: Base) {
// base.a, base.b는 접근 불가
// base.c와 base.d는 접근 가능(같은 모듈 안에 있으므로)
// Base.Nested는 접근 불가, Nested::e 역시 접근 불가
}
가시성 지시자와 클래스의 관계
++ 관계(relationship) ++
- 연관(association)
- 의존(dependency)
- 집합(aggregation) "has a"
- 구성(composition) "owns a"
package com.example.pp160
class Patient(val name: String) {
fun doctorList(d: Doctor) { // 인자로 참조
println("Patient: $name, Doctor: ${d.name}")
}
}
class Doctor(val name: String) {
fun patientList(p: Patient) { // 인자로 참조
println("Doctor: $name, Patient: ${p.name}")
}
}
fun main() {
val doc1 = Doctor("Kimsabu") // 객체가 따로 생성된다.
val patient1 = Patient("Kildong")
doc1.patientList(patient1)
patient1.doctorList(doc1)
}
연관 관계 나타내기 예제
Association
package com.example.pp161
class Patient(val name: String, var id: Int) {
fun doctorList(d: Doctor) {
println("Patient: $name, Doctor: ${d.name}")
}
}
class Doctor(val name: String, val p: Patient) {
val customerId: Int = p.id
fun patientList() {
println("Doctor: $name, Patient: ${p.name}")
println("Patient Id: $customerId")
}
}
fun main() {
val patient1 = Patient("Kildong", 1234)
val doc1 = Doctor("Kimsabu", patient1)
doc1.patientList()
}
의존 관계 나타내기 예제
Dependency
package com.example.pp162
// 여러 마리의 오리를 위한 List 매개 변수
class Pond(_name: String, _members: MutableList<Duck>) {
val name: String = _name
val members: MutableList<Duck> = _members
constructor(_name: String): this(_name, mutableListOf<Duck>())
}
class Duck(val name: String)
fun main() {
// 두 개체는 서로 생명주기에 영향을 주지 않는다.
val pond = Pond("myFavorite")
val duck1 = Duck("Duck1")
val duck2 = Duck("Duck2")
// 연못에 오리를 추가 - 연못에 오리가 집합한다.
pond.members.add(duck1)
pond.members.add(duck2)
// 연못에 있는 오리들
for(duck in pond.members) {
println(duck.name)
}
}
집합 관계 나타내기 예제
Aggregation
package com.example.pp163
class Car(val name: String, val power: String) {
private var engine = Engine(power) // Engine 클래스 객체는 Car에 의존적
fun startEngine() = engine.start()
fun stopEngine() = engine.stop()
}
class Engine(power: String) {
fun start() = println("Engine has been started.")
fun stop() = println("Engine has been stopped.")
}
fun main() {
val car = Car("tico", "100hp")
car.startEngine()
car.stopEngine()
}
구성 관계 나타내기 예제
Composition
'Kotlin' 카테고리의 다른 글
Kotlin #9 : 객체, 데이터 클래스, Companion 객체, object, singleton, 추상 클래스, 인터페이스 230222 (0) | 2023.02.23 |
---|---|
Kotlin #8 : 코틀린의 프로퍼티, 자바의 필드, 지연 초기화, lazy, 위임 230220 (0) | 2023.02.22 |
Kotlin #6 : 상속과 클래스 230217 (0) | 2023.02.20 |
Kotlin #5 : 객체지향 프로그래밍 230216 (0) | 2023.02.17 |
Kotlin #4 : 예외처리 230216 (0) | 2023.02.16 |
댓글