깨알 개념/Kotlin

[Kotlin] 확장 함수(Extension functions)

interfacer_han 2023. 12. 16. 18:09

#1 코드 - 코틀린

#1-1

fun main() {
    var testInteger : Int = 7
    testInteger = testInteger.plusAndMultiply(3, 5)
    println("${testInteger}") // 결과로 50이 출력된다.
}

fun Int.plusAndMultiply(plusValue : Int, multiplyValue : Int) : Int {
    return (this + plusValue) * multiplyValue
}

이 코드는 확장 함수(Extension functions)를 사용하는 예이다.

확장 함수란 기존 클래스의 멤버 함수인 것처럼 호출할 수 있지만, 해당 클래스에 직접 정의된 멤버가 아닌 외부에서 정의된 함수다. 확장 함수의 문법은 아주 간단하다. 함수 이름 앞에 클래스 또는 인터페이스 명을 붙이기만 하면 된다.
여담으로, 자바에는 코틀린의 확장 함수와 같은 기능은 없지만 비슷한 역할을 수행하는 Default method가 있다.

 

#1-2

fun main() {
    val hongGilDong = Person("홍길동", 175, 65, 3579)
    Person.hello()
    hongGilDong.selfIntroduction()
    hongGilDong.introduceBMI()
    Person.bye()
}

class Person (val name: String, val height: Int, val weight: Int, private val memberNumber : Int) {

    companion object {
        fun hello() {
            println("Hello")
        }
        fun bye() {
            println("GoodBye")
        }
    }
    
    fun selfIntroduction() {
        println("My name is ${name}. I am ${height}cm tall and weigh ${weight}kg")
    }
}

fun Person.introduceBMI() {
    val weightKG = this.weight.toDouble()
    val heightM = this.height.toDouble() / 100
    val BMI = weightKG / (heightM * heightM) // heightM * heightM에 괄호를 씌우지 않으면 BMI == weightKG가 되어버리니 주의
    val roundedBMI = "%.1f".format(BMI)
    println("My BMI is ${roundedBMI}")
}

/* ↓ 에러가 발생하는 코드
fun Person.introduceMemberNumber() {
    println("My memberNumber is ${this.memberNumber}")
}
*/

/* 출력 결과
Hello
My name is 홍길동. I am 175cm tall and weigh 65kg
My BMI is 21.2
GoodBye
*/

확장 함수는 기존 클래스의 멤버 함수인 것처럼 호출할 수 있을 뿐, 실제로 해당 클래스의 멤버인 것은 아니기 때문에 private이나 protected 멤버에는 접근할 수 없다. 예를 들어, 위 코드에서 Person 객체의 memerNumber 프로퍼티에는 확장 함수가 접근할 수 없다.

 

#1-3

fun main() {
    val hongGilDong = Person("홍길동", 175, 65, 3579)
    
    hongGilDong.introduceType()
}

interface Animal {
    val type : String
}

class Person (val name: String, val height: Int, val weight: Int, private val memberNumber : Int) : Animal {
    override val type = "mammal"
    
    // ...
}

fun Animal.introduceType() {
    println("My type is ${this.type}")
}

/* 출력 결과
My type is mammal
*/

이과 같이 인터페이스에도 확장 함수를 적용할 수 있다.

 

#2 요약

확장 함수를 통해, 원래의 코드를 건드리지 않고 기능을 추가한다.

 

#3 이 개념이 사용된 글

 

[백준] 10845 - 큐

#1 알고리즘 java.util.Stack과는 달리 java.util.Queue는 클래스가 아니라 인터페이스다. 나는 java.util.Queue 인터페이스를 구현한 클래스인 LinkedList를 Queue로서 사용했다. last()는 확장 함수(Extension functions)

kenel.tistory.com

 

[백준] 2606 - 바이러스

#1 알고리즘 #2 코드 (코틀린) fun main() { readln() // 컴퓨터의 갯수는 풀이에 사용하지 않는다. val connectionCount = readln().toInt() val connections : ArrayList = ArrayList() for(i : Int in 0..

kenel.tistory.com