5-2. 고급 함수와 함수형 프로그래밍 활용하기 : 확장
5장
5-1. 고급 함수와 함수형 프로그래밍 활용하기 : 코틀린을 활용한 함수형 프로그래밍
5-2. 고급 함수와 함수형 프로그래밍 활용하기 : 확장
5-3. 고급 함수와 함수형 프로그래밍 활용하기 : 확장 프로퍼티
5-4. 고급 함수와 함수형 프로그래밍 활용하기 : 동반 확장
5-5. 고급 함수와 함수형 프로그래밍 활용하기: 수신 객체가 있는 호출 가능 참조
5-2. 확장
실무에서 기존 클래스를 확장해야 하는 경우가 자주 있다.
한 클래스 안에 속한 메서드를 모두 사용하지 않지만, 모든 메서드를 다 import할 경우 실용적이지 않다.
이 경우 여러 프로그램 모듈에 함께 사용되는 메서드를 서로 분리해 유지하는 방법이 있다.
자바의 경우 이런 추가 메서드를 별도의 유틸리티 클래스로 묶어 사용하지만,
코틀린은 마치 멤버인 것 처럼 쓸 수 있는 함수나 프로퍼티를 클래스 밖에서 선언할 수 있게 해주는
확장이라는 기능을 재공한다. 확장을 사용하면 기존 클래스를 변경하지 않아도 새로운 기능으로 기존 클래스를
확장할 수 있어서 개방/폐쇠 디자인 원칙(OCP)를 지원할 수 있다.
1) 확장 함수
확장 함수는 어떤 클래스의 멤버인 것 처럼 호출할 수 있는(실제로는 멤버 x) 함수를 뜻한다.
이런 함수를 정의할 때는 함수를 호출할 때 사용할 수신 객체의 클래스 이름을 먼저 표시하고,점을 추가한 다음에 함수 이름을 표시한다. 예를들어 String 타입에 문자열의 길이를 특정 길이 이하로 제한하는함수를 추가해 확장하고 싶다면, 아래와 같이 구현하면 된다.
fun String.truncate(maxLength: Int): String{
return if(length <= maxLength) this else substring(0, maxLength)
}
fun main() {
println("ByeBye".truncate(10)) // ByeBye
println("ByeBye".truncate(3)) // Bye
}
정의한 이후에는 다른 String 클래스 멤버와 마찬가지로 사용하면 된다.
일반 멤버와 비슷하게, 수신 객체에 this로 접근 가능하다. 하지만 확장 함수 자체는 수신 객체가 속한 클래스의
private 멤버에 접근할 수 없다.
class Person(var firstName: String, private var lastName: String)
fun Person.showInfo() = println("$firstName $lastName") // ERROR
// Cannot access 'lastName': it is private in 'Person'
클래스 본문 안에서 확장 함수를 정의할 수 있으며, 이 경우 확장 함수가 수신 객체의 멤버인 동시에 확장 함수가 된다.
이 경우 클래스의 비공개 멤버에 접근 가능하다.
class Person(var firstName: String, private var lastName: String){
fun Person.showInfo() = println("$firstName $lastName") // OK
}
확장 함수는 바인딩된 호출 가능 참조 위치에도 사용할 수 있다.
class Person(var name: String, var age: Int)
fun Person.hasName(name: String) = name.equals(this.name, ignoreCase = true)
fun main() {
var f = Person("유재석", 30)::hasName
println(f("유재석"))
println(f("유퀴즈"))
}
다음글