일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Kotlin
- 유니티
- Unity
- firebase
- submodule sourcetree
- 안드로이이드 submodule
- 안드로이드개발
- github submodule
- 개발
- 서브모듈 pull
- GIT
- java
- 코틀린
- Android
- Android Studio
- submodule pull
- 2d게임
- 안드로이드
- 앱개발
- 게임개발
- 카페오냥
- github
- 타이쿤
- 앱
- 내 맘대로 정리한 안드로이드
- 티스토리
- 서브모듈 sourcetree
- DataBinding
- gitlab submodule
- 쿼터뷰
- Today
- Total
Uing? Uing!!
[내 맘대로 정리한 Kotlin] 확장 함수와 확장 프로퍼티: 직접 수정할 수 없는 클래스에 함수&프로퍼티 추가하기 본문
클래스, 메소드, 프로퍼티
Kotlin으로 개발을 하다 보면 클래스와 메소드, 프로퍼티를 자주 사용하게 된다.
아래는 Dog라는 객체를 클래스르 만들어 활용하는 대표적인 예시이다.
class Dog(var name: String){ // 클래스
fun bark() = println("멍!") // 메소드
}
var happy = Dog("Happy")
happy.bark() // Dog.bark() 메소드 호출
여기에 새로운 메소드를 추가하고 싶다면, 간단하게 클래스 안에 새로운 메소드를 추가하면 된다.
class Dog(var name: String){
fun bark() = println("멍!")
fun whine() = println("끼잉...") // 새로운 메소드
}
직접 수정할 수 없는 클래스
하지만 직접 클래스를 수정할 수 없는 경우라면 어떨까?
1. (안드로이드를 기준으로) Context나 TextView에 새로운 메소드를 추가하고 싶다면?
2. 또는 직접 수정할 수 없는 외부 라이브러리의 클래스를 사용하는 경우라면?
3. 극단적으로 어떤 이유가 있어서 String, Integer, List처럼 기본적인 클래스에 새 메소드를 추가하고 싶다면?
위의 3가지 경우 중 2번의 케이스를 예로 들어 보자.
아래는 제일 처음에 언급한 Dog 클래스이다.
class Dog(var name: String){ // 클래스
fun bark() = println("멍!") // 메소드
}
맨 위의 방식과 똑같이 이 클래스에 whine()이라는 메소드를 추가해주고 싶다.
하지만 이번에는 이 Dog라는 클래스가 우리가 직접 건드릴 수 있는 클래스가 아니라고 하자.
이런 경우에 사용할 수 있는 방법이 확장 함수이다.
확장 함수(Extention Function)
확장 함수를 사용하면, Dog 클래스를 직접 수정하지 않고도 이 클래스에 새 메소드를 만들어줄 수 있다.
사용 방법은 간단하다. 일반 함수를 만들듯이 확장 함수를 만들면 된다.
fun main() {
var happy = Dog("Happy")
happy.whine()
}
fun Dog.whine() = println("끼잉...") // 확장 함수 정의
이렇게 Dog.whine() 함수를 정의해 주면, 마치 원래 있었던 메소드인 양 사용할 수 있다.
확장 프로퍼티(Extention Property)
확장 프로퍼티는 확장 함수와 마찬가지로, 직접 수정할 수 없는 클래스에 변수를 추가해주고 싶을 때 쓸 수 있다.
단, 기존 클래스 내에 직접 값을 저장할 수는 없으므로 getter property로만 설정할 수 있다.
가령 위의 Dog 클래스에서 '이름의 앞 3글자'를 받아와 identifier로 사용하고 싶다고 하자.
(마찬가지로 직접 Dog 클래스가 포함된 파일을 수정할 수 없는 상황이다.)
이렇게 Dog.identifier 확장 프로퍼티를 만들어 주면 저장된 이름에서 3글자를 받아와 출력하도록 할 수 있다.
fun main() {
var happy = Dog("Happy")
println(happy.identifier) // "Hap" 출력
}
val Dog.identifier: String // 확장 프로퍼티
get() = name.substring(0,3) // getter 설정
사실 기존에 있는 다른 프로퍼티를 수정하도록 getter&setter를 모두 설정해주는 것도 가능은 하지만,
이렇게 되면 확장 프로퍼티를 setter로 수정했는데 기존에 정의되어 있던 다른 변수가 수정되는 예기치 못한 상황이 발생할 수 있다.
예를 들어 위의 identifier를 수정하면 기존의 Dog.name이 수정된다고 하면,
identifier를 수정하려고 했는데 강아지의 이름이 변하는 의도하지 않는 상황이 발생하게 된다.
따라서 적어도 setter에 있어서는 확장 프로퍼티보다는 확장 함수를 쓰는 것이 더 적절한 방법일 듯하다.
마치며
확장 함수와 확장 프로퍼티는 많은 편의성을 제공해 주지만, 꼭 필요한 경우에만 사용하는 것이 좋다.
특히 위에 언급한 사례 중 'String, Integer, List처럼 기본적인 클래스에 확장 함수 & 확장 프로퍼티 설정하기'는 꼭 필요한 경우가 아니라면 사용을 지양하는 편이 좋다.
그 이유에 대해서는 다음 포스팅에서 이야기하도록 하겠다.
'Kotlin' 카테고리의 다른 글
[내 맘대로 정리한 Kotlin] @CallSuper 어노테이션: 상속은 허용하되, 덧붙이는 것만 허용하고 싶다면? (0) | 2021.03.31 |
---|---|
[내 맘대로 정리한 Kotlin] @JvmOverloads: constructor를 일일이 상속받아 만들기 귀찮다면! (0) | 2021.03.30 |
[내 맘대로 정리한 Kotlin] vararg(가변인자)로 파라미터 원하는 개수만큼 받기 (0) | 2020.12.11 |
[내 맘대로 정리한 Kotlin] let으로 null-check 하기 (0) | 2020.11.17 |
[내 맘대로 정리한 Kotlin] isEmpty와 isBlank의 차이점 (0) | 2020.09.30 |