개발 언어/코틀린
코틀린(Kotlin) | 클래스 - 확장 함수와 확장 프로퍼티
jjiiiinn
2019. 6. 22. 16:29
728x90
확장
- 코틀린의 확장 기능을 통해 기존 클래스의 함수(메서드) 및 프로퍼티를 확장 정의하여 사용할 수 있다.
- 확장 불가 클래스(final) 또는 짧은 범위에서 특정 클래스의 기능을 추가/수정할 경우 유용하다.
- 호출 시점에 부가 비용이 발생하지 않는다.
확장 함수 (Extension function)
- [확장 하려는 대상 클래스].함수명() 형식으로 정의한다.
- 코틀린의 최상위 객체인 Any에 확장 함수를 정의하면 모든 객체에서 사용 가능하다.
- 확장 함수의 경우 내부에서만 사용할수 있는 private, protected 멤버에는 접근하지 못한다.
- 확장 함수와 클래스 멤버 함수의 이름이 같은경우 멤버 함수의 우선순위가 더 높기때문에 클래스 내의 멤버 함수가 호출 된다.
class Person(val name: String) {
fun walk() = "person is walking"
}
// 확장 메서드
fun Person.walk() = "unknown function"
fun Person.nameToUpperCase() = this.name.toUpperCase()
fun main() {
val person: Person = Person("park jin")
println(person.nameToUpperCase()) // PARK JIN
// 멤버 메서드가 우선시 됨
println(person.walk()) // person is walking
}
- 확장 함수의 this는 확장 하려는 객체(위에서는 Person)을 가리킨다.
- 확장시 상속을 사용하지 않으며 내부적으로 수신자 클래스를 첫번째 인자로 받는 정적 메서드로 변환한다.
ExtensionsKt.attachStringToBothSide(String);
정적 바인딩 vs 동적 바인딩
- 확장 함수의 경우 오버라이드와 다르게 정적 바인딩 처리된다.
정적 바인딩 vs 동적 바인딩
정적 바인딩: 컴파일 시간에 성격이 결정 된다.
동적 바인딩: 런타임시에 성격이 결정 된다.
확장 함수
open class Person
class Student: Person()
fun Person.name() = "person"
fun Student.name() = "student"
fun printName(person: Person) {
println(person.name()) // 정적 바인딩되어 person 출력
}
fun main() {
printName(Student())
}
오버라이드
open class Person {
open fun printName() = "person"
}
class Student: Person() {
override fun printName() = "student"
}
fun printName(person: Person) {
println(person.printName()) // 동적 바인딩 되어 student 출력
}
fun main() {
printName(Student())
}
확장 프로퍼티 (Extension Property)
- 기존 객체에 실제로 프로퍼티를 추가하는 방식이 아니기 때문에 상태를 저장할 수는 없음.
- getter, setter를 추가하여 구현한다.
class Person {
var friendList = mutableListOf<String>()
}
// 확장 프로퍼티(friend)
var Person.friend: String
get() = this.friendList.last()
set(value) { this.friendList.add(value) }
fun main() {
val person = Person()
person.friend = "park jin1"
person.friend = "park jin2"
println(person.friend) // park jin2
}
출처
728x90