코틀린 확장함수
### ✅ **Kotlin 확장 함수 (Extension Function)**
✔ **기존 클래스(기본 클래스 포함)를 수정하지 않고도 새로운 기능을 추가할 수 있음!**\
✔ **즉, 기존 코드 변경 없이, 내가 원하는 함수를 추가할 수 있음!**\
✔ **확장 함수는 `클래스명.함수명` 형식으로 선언함.**
* * * * *
✅ **1\. 기본 확장 함수 예제**
---------------------
```
fun String.addPrefix(): String {
return "Prefix_$this"
}
println("Kotlin".addPrefix()) // ✅ "Prefix_Kotlin"
```
📌 **설명:**\
✔ `String.addPrefix()` → `String` 클래스에 `addPrefix()`라는 확장 함수를 추가\
✔ `this` → 확장 함수 내부에서 원래 객체(`String`)를 가리킴\
✔ `"Kotlin".addPrefix()` → `"Kotlin"` 문자열에 확장 함수 적용
* * * * *
✅ **2\. 확장 함수의 활용 예제**
----------------------
### 🔹 **1️⃣ Int 확장 함수 만들기**
```
fun Int.isEven(): Boolean {
return this % 2 == 0
}
println(10.isEven()) // ✅ true
println(7.isEven()) // ✅ false
```
📌 **`isEven()`을 사용하여 정수가 짝수인지 쉽게 판별 가능!**
* * * * *
### 🔹 **2️⃣ List 확장 함수 (평균값 계산)**
```
fun List<Int>.averageValue(): Double {
return if (this.isEmpty()) 0.0 else this.sum().toDouble() / this.size
}
val numbers = listOf(10, 20, 30, 40)
println(numbers.averageValue()) // ✅ 25.0
```
📌 **리스트의 평균값을 구하는 기능을 확장 함수로 추가!**
* * * * *
### 🔹 **3️⃣ ViewBinding에서 자주 쓰이는 확장 함수 (안드로이드 예제)**
```
fun View.show() {
this.visibility = View.VISIBLE
}
fun View.hide() {
this.visibility = View.GONE
}
```
📌 **안드로이드 개발할 때 `View` 객체를 간편하게 보이거나 숨길 수 있음!**\
📌 **이제 `button.show()` 또는 `textView.hide()`처럼 간단하게 사용 가능!** 🚀
* * * * *
✅ **3\. 확장 함수의 한계 (오버라이딩 불가능)**
-------------------------------
✔ 확장 함수는 **기존 클래스의 private/protected 멤버에는 접근할 수 없음.**\
✔ 확장 함수는 **클래스의 실제 메서드를 오버라이딩할 수 없음!**
```
open class Parent {
open fun greet() {
println("Hello from Parent")
}
}
class Child : Parent() {
override fun greet() {
println("Hello from Child")
}
}
// 확장 함수 추가
fun Parent.greet() {
println("Hello from Extension")
}
val parent: Parent = Child()
parent.greet() // ✅ "Hello from Child" (확장 함수가 아닌 원래 메서드가 호출됨)
```
📌 **즉, 확장 함수는 클래스의 실제 메서드를 재정의하지 않음!**\
📌 **이유: 확장 함수는 정적으로 결정되므로, 런타임 다형성이 적용되지 않음.**
* * * * *
✅ **4\. 확장 프로퍼티 (Extension Property)**
--------------------------------------
✔ **프로퍼티도 확장 가능하지만, `field`(필드)를 가질 수 없음.**\
✔ **즉, 값을 저장하는 게 아니라 `getter`만 가능!**
```
val String.firstChar: Char
get() = this[0]
println("Kotlin".firstChar) // ✅ 'K'
```
📌 **`firstChar`를 `String`의 확장 프로퍼티로 추가하여 첫 번째 문자를 가져올 수 있음.**
* * * * *
✅ **5\. 정리**
------------
| **기능** | **설명** | **예제** |
| --- | --- | --- |
| **확장 함수 기본** | 기존 클래스에 함수 추가 | `"Hello".addPrefix()` |
| **확장 함수 활용** | `Int`, `List`, `View` 등에 적용 가능 | `10.isEven()` / `list.averageValue()` |
| **한계** | 기존 메서드 오버라이딩 불가 | `parent.greet()`는 원래 메서드 호출됨 |
| **확장 프로퍼티** | `getter`만 가능, `field` 없음 | `"Kotlin".firstChar` |
📌 **즉, 확장 함수는 기존 클래스의 기능을 손쉽게 추가하는 강력한 기능!** 🚀\
### ✅ **Kotlin 확장 함수(Extension Function)는 "진짜 메서드"가 아니다!**
✔ **확장 함수는 기존 클래스에 새로운 메서드를 추가하는 것처럼 보이지만, 실제로는 정적 함수(Static Function)처럼 동작함.**\
✔ **즉, 기존 클래스에 직접 추가되는 것이 아니라, "외부에서 추가된 유틸리티 함수"처럼 동작함.**\
✔ **따라서 확장 함수는 "클래스의 메서드처럼 보이지만, 실제로는 해당 클래스의 인스턴스에 포함되지 않음."**
* * * * *
✅ **1\. 확장 함수는 실제 메서드가 아님!**
----------------------------
```
fun String.addPrefix(): String {
return "Prefix_$this"
}
println("Kotlin".addPrefix()) // ✅ "Prefix_Kotlin"
```
📌 **이렇게 `addPrefix()`를 `String`에 추가했지만, `String` 클래스의 진짜 메서드가 된 것은 아님!**\
📌 **실제 `String` 클래스 내부를 보면 `addPrefix()`가 포함되지 않음.**\
📌 **즉, 확장 함수는 그냥 "추가적인 유틸 함수"일 뿐, 원래 클래스의 일부가 아님.**
* * * * *
✅ **2\. 확장 함수의 내부 동작 (컴파일 후)**
------------------------------
✔ 컴파일하면, 확장 함수는 **정적 메서드(Static Function)처럼 동작함.**\
✔ 즉, 내부적으로는 **"클래스를 확장하는 것이 아니라, 매개변수로 인스턴스를 받는 일반적인 함수"로 변환됨.**
예를 들어, 위의 `addPrefix()` 확장 함수는 컴파일되면 이렇게 변환됨:
```
fun addPrefix(str: String): String {
return "Prefix_$str"
}
println(addPrefix("Kotlin")) // ✅ "Prefix_Kotlin"
```
📌 **즉, `"Kotlin".addPrefix()`는 `addPrefix("Kotlin")`처럼 변환됨!**\
📌 **원래 `String` 클래스 안에 포함되는 게 아니라, 외부에서 따로 동작하는 함수일 뿐임.**
* * * * *
✅ **3\. "진짜 메서드"가 아니라는 증거: 오버라이딩 불가능**
--------------------------------------
✔ **클래스 내부의 "진짜 메서드"는 `override`가 가능하지만, 확장 함수는 불가능!**\
✔ **확장 함수는 클래스의 일부가 아니므로 다형성(Polymorphism) 적용이 안 됨!**
```
open class Parent {
open fun greet() {
println("Hello from Parent")
}
}
class Child : Parent() {
override fun greet() {
println("Hello from Child")
}
}
// 확장 함수 추가
fun Parent.greet() {
println("Hello from Extension")
}
val parent: Parent = Child()
parent.greet() // ✅ "Hello from Child" (확장 함수가 실행되지 않음!)
```
📌 **`greet()` 확장 함수가 선언되었지만, `parent.greet()`는 확장 함수가 아니라 원래 `Child` 클래스의 `greet()`가 실행됨.**\
📌 **이유? 확장 함수는 "진짜 메서드"가 아니라, "정적 함수처럼 동작"하기 때문!**
* * * * *
✅ **4\. 진짜 메서드 vs 확장 함수 차이**
----------------------------
| | **진짜 메서드 (클래스 내부 메서드)** | **확장 함수 (Extension Function)** |
| --- | --- | --- |
| **클래스 내부에 포함?** | ✅ 포함됨 | ❌ 포함되지 않음 (컴파일 후 정적 함수처럼 동작) |
| **override 가능?** | ✅ 가능 (`open`, `override` 사용) | ❌ 불가능 (정적 함수처럼 동작) |
| **다형성 적용?** | ✅ 적용됨 | ❌ 적용되지 않음 |
| **호출 방식** | `obj.method()` | `obj.extensionMethod()` (실제로는 `extensionMethod(obj)`) |
📌 **즉, 확장 함수는 "진짜 메서드"가 아니라, 클래스의 일부가 아닌 독립적인 유틸리티 함수야!** 🚀
댓글
댓글 쓰기