Uing? Uing!!

[내 맘대로 정리한 Kotlin] 확장 함수와 확장 프로퍼티: 직접 수정할 수 없는 클래스에 함수&프로퍼티 추가하기 본문

Kotlin

[내 맘대로 정리한 Kotlin] 확장 함수와 확장 프로퍼티: 직접 수정할 수 없는 클래스에 함수&프로퍼티 추가하기

Uing!! 2020. 12. 13. 21:14
반응형

클래스, 메소드, 프로퍼티

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] 확장 함수, 확장 프로퍼티를 사용할 때 주의할 점: 확장 함수가 정의되

확장 함수와 프로퍼티 확장 함수와 프로퍼티는 직접 수정할 수 없는 클래스에 추가적인 함수나 프로퍼티를 설정해 주는 방법이다. 이에 대한 자세한 설명은 아래 포스팅에 정리되어 있다. [내

holika.tistory.com

 

반응형
Comments