본문 바로가기
kotlin/문법

[kotlin] 확장함수

by 코드 이야기 2023. 5. 11.
728x90

 

 

확장함수

기존 코드를 재작성하지 않고, 메서드를 추가할 수 있는 기능.

정적 메서드 호출에 대한 문법적 편의를 제공하는 기능.

 

사용 방법

아래와 같이 다양한 방법으로 사용할 수 있다.

fun main() {
    val str: String = "otter66"
    println(str.lastChar())
}


1. fun String.lastChar(): Char = this.get(this.lastIndex)
2. fun String.lastChar(): Char = this[this.lastIndex]
3. fun String.lastChar(): Char = get(lastIndex)

1, 2번의 경우 수신객체에 this를 사용해 접근한 방법이다.

3번과 같이 수신객체를 this 없이 접근할 수도 있다.

 

아래와 같이 수신객체의 타입을 지정하는 방법도 있다.

 

 

그렇다면 수신객체란 무엇일까?

수신 객체, 수신 객체 타입

fun String(1).lastChar(): Char = this(2).get(this(2).lastIndex)

(1) 수신객체타입 (클래스)

(2) 수신객체 (클래스의 인스턴스 객체)

 

 

이렇게 기존 클래스에서 무분별하게 메서드를 추가로 만들 수 있는걸까?

객체지향적인 설계가 된 클래스가 외부에서 무분별하게 사용되며 객체의 캡슐화, OOP를 저해할 수 있지 않을까?

하지만 확장함수는 일반적으로 캡슐화를 깰 수 없다.

확장함수와 캡슐화

class Test() {
    private val privateTest = "private_otter66"
    val publicTest = "public_otter66"
}

1. fun Test.getPublic(): String = publicTest
2. fun Test.getPrivate(): String = privateTest

확장함수는 일반적으로 private, protected 처럼 외부에서 사용이 불가한 멤버를 사용할 수 없다.

따라서 1번 코드처럼 public 멤버는 사용할 수 있지만,

2번 코드의 경우 private을 참조하려고 하여 에러가 발생한다.

 

 

 

일반적으로?? 일반적으로 안된다는 것은 된다는 경우도 있다는 말이다.

더보기

reflection을 사용해 확장함수로 캡슐화 위반하기.

fun main() {
    val test: Test = Test()
    println(test.getPrivate())
}

class Test() {
    private val privateTest = "private_otter66"
    val publicTest = "public_otter66"
}

fun Test.getPublic(): String = publicTest
fun Test.getPrivate(): String {
    val field = Test::class.java.getDeclaredField("privateTest")
    field.isAccessible = true
    return field.get(this) as String
    // set도 있다!
}

하지만 이 부분은 넘어가도록 하자... 알지 말자... ;

코드를 짜는 나 자신과 코드를 읽게 될 모든 사람들의 눈건강과 심리적 안정감을 위하여...

 

추가적인 특징으로는 오버라이드가 불가하다는 것이다.

실행 이후 결정되는(동적인) 방법인 메서드 오버라이드를 지원하지 않는다.

 

 

 

 

728x90

'kotlin > 문법' 카테고리의 다른 글

[kotlin] collection (List, Set, Map)  (0) 2021.01.14
[kotlin] arrays 배열  (0) 2021.01.14
[kotlin] Functions 함수  (0) 2021.01.13
[kotlin] loop (반복문) for, while, do while  (0) 2020.12.30
[kotlin] 조건문 (if, when), 엘비스(elvis)  (0) 2020.12.28

댓글