Kotlin 시리즈의 확장 함수와 속성

오늘 Kotlin의 확장 함수와 속성에 대해 이야기합시다.
함수와 속성을 확장하는 것은 명지의를 보면 현재 존재하는 클래스를 바탕으로 함수와 속성을 추가할 수 있다. 단지 이러한 함수와 속성이 클래스의 외부에 정의되어 있을 뿐이다. 궁금하지 않니?그럼 같이 봅시다.

확장 함수


문자열의 마지막 문자를 얻기 위해 스트링 클래스에 구성원 함수 lastChar 를 추가하는 예를 들어 분석합니다.코드부터.
Kotlin 코드
package expand
fun String.lastChar(): Char = this.get(this.length - 1)

그래, 잘못 보지 않았어. 가방 설명을 제외하고는 코드가 한 줄밖에 없어. 그 정의 규칙은 이렇다.fun . : = .여기this는 확장할 클래스의 대상을 나타낸다. 여기가string 대상이기 때문에string 클래스에 접근할 수 있는 모든 속성과 방법을 호출할 수 있다.이어서 우리는 일반적인 방법처럼 우리의 확장 방법을 호출할 수 있다. 아무런 차이도 없다. 아래와 같다.
Kotlin에서 호출
import expand.lastChar

//        Kotlin        
fun main(args: Array){
    println("Kotlin".lastChar())
}

사용하기 전에 함수를 가져온 다음 . 호출을 사용해야 합니다.
Java에서 호출
import expand.ExpandFunKt;

public class Main {
    public static void main(String[] args) {
        System.out.println(ExpandFunKt.lastChar("Kotlin"));
    }
}

자바에서도 가져오기가 필요합니다. 함수가 아니라 파일 이름으로 만든 클래스만 가져오고, 정적 방법처럼 우리의 확장 함수를 호출해서 문자열을 매개 변수로 가져오면 됩니다.물론 Kotlin은 프로필을 추구하는 언어로 위의 확장 함수는 생략this할 수 있다. 아래와 같다.
fun String.lastChar(): Char = get(length - 1)

그러나 우리의 확장 함수는 클래스의 봉인성을 파괴하는 것을 허용하지 않습니다. 즉, 확장할 때 클래스의 개인 속성과 보호된 속성에 접근할 수 없습니다.때때로 Kotlin에서 가져온 함수가 이름이 바뀔 수도 있습니다. 이 때 as 키워드를 가져오는 동시에 그 별명을 지정할 수 있습니다. 호출할 때 이 별명을 사용하면 됩니다. 아래와 같습니다.
import expand.lastChar as last

fun main(args: Array){
    println("Kotlin".last())
}

확장 함수를 다시 쓸 수 없습니다


사실 네가 위의 예를 완전히 이해했다면 왜 확장 함수를 다시 쓸 수 없는지 순간적으로 이해할 수 있을 것이다.확장 함수가 자바에서 호출되는 형식을 살펴보자. 사실은 하나의 종류의 정적 방법을 호출한 것이다. 여기서 자바의 지식점과 관련된다.우리는 자바의 예를 써서 다음과 같은 것을 설명한다.
Java 코드
//  
public class Father {
    public void say(){
        System.out.println("    。。。");
    }
}

//      
public class Son extends Father{
    public void say(){
        System.out.println("    。。。");
    }
}

그리고 다음 코드로 테스트를 해볼게요.
public class Main {
    public static void main(String[] args) {
        Father father = new Father();
        father.say();

        Son son = new Son();
        son.say();

        Father obj = new Son();
        obj.say();
    }
}

출력은 다음과 같습니다.
    。。。
    。。。
    。。。

이것은 자바의 기초 지식입니다. 여러분은 이의가 없으시죠. 이어서 위의say() 방법을static로 수정해 봅시다. 아래와 같이.
public class Father {
    public static void say(){
        System.out.println("    。。。");
    }
}

public class Son extends Father{
    public static void say(){
        System.out.println("    。。。");
    }
}

테스트 코드
public class Main {
    public static void main(String[] args) {
        Father father = new Father();
        father.say();

        Son son = new Son();
        son.say();

        Father obj = new Son();
        obj.say();
    }
}

우선 위의 테스트 코드는 오류가 발생하지 않습니다. 아마도 우리는 평소에 이렇게 정적 방법을 사용하지 않을 것입니다. 여기는 단지 문제를 설명하기 위해서입니다.실행 결과는 다음과 같습니다.
    。。。
    。。。
    。。。

특히 세 번째 운행 결과를 보면 그렇다 .다음은 일반 구성원 변수의 재작성으로 인한 다태성은 우리가 사용하고 있기 때문이다.위의 규칙은 Kotlin에서도 똑같이 적용됩니다. 다만 확장 함수가 다중화되지 않은 것으로 바뀌었을 뿐입니다. (사실 확장 함수가 자바에서 호출될 때 정적 함수로 처리된다는 것을 기억하면 이해할 수 있습니다.) 다음은 Kotlin으로 다음 장면을 재현합니다.
Kotlin 코드
package kt

//  
open class Father{
    open fun say(){
        println("    。。。")
    }
}

package kt

//  
class Son: Father() {
    override fun say() {
        println("    。。。")
    }
}

위의 코드는 새로운 문법과 관련이 있습니다. 우선 Kotlin에서 모든 종류의 기본값은 final 이고 계승할 수 없습니다. 앞에 open 수식자를 추가해야 계승할 수 있습니다.그 다음에 상속은 extends 키워드를 사용하지 않고 :를 사용한다. 또한 뒤의 상속류는 클래스 이름을 쓰는 것이 아니라 ()도 써야 한다. 사실 이 안은 하나이다. 이것은 구조 함수를 나타낸다. 이것은 우리 뒤의 내용을 상세하게 소개할 것이다.마지막으로 주의 방법의 재작성은 함수 앞에 override 키워드를 써야 합니다.테스트 코드
package kt

fun main(args: Array){
    val father1 = Father();
    father1.say();

    val son = Son();
    son.say();

    val obj: Father = Son();
    obj.say();
}

결과 내보내기
    。。。
    。。。
    。。。

이제 우리는 이 두 종류를 확장하기 시작하여 이 두 종류 모두 함수sayName()를 확장한다. 아래와 같다.
fun Father.sayName() = println("Father")

fun Son.sayName() = println("Son")

다음은 확장 함수가 다시 쓰였는지, 즉 다태성을 갖추고 있는지 시험해 봅시다.
val obj2: Father = Son()
obj2.sayName()

결과 내보내기
Father

위에서 약간 수다스러운 절차를 통해 우리는 확장 함수를 다시 쓸 수 없다는 것을 검증했다.마지막으로 한 가지 더 말하자면, 만약 하나의 클래스의 구성원 함수와 확장 함수가 같은 방법으로 서명한다면, 구성원 함수는 우선적으로 사용될 것이다.

확장 속성


확장 함수를 습득하면 확장 속성을 배우기가 좀 쉽다.우리는 여전히 문장의 처음 장면을 말한다. 우리는 String 클래스에 확장 속성 lastChar 을 정의한다. 아래와 같다.
val String.lastChar: Char get() = get(length - 1)

String은 변할 수 없기 때문에 확장 속성은 val 로 명시됩니다. 또한 확장된 속성 lastChar 은 클래스 내부에 있지 않기 때문에 초기 값을 부여하고 초기화할 수 없습니다. 저장할 곳이 없기 때문에 Getter 방법을 추가해서 호출될 때 값을 되돌려받을 수 밖에 없습니다.물론 StringBuilder의 확장 속성이라면 확장된 속성을 var로 표시하고 Getter와setter 방법을 추가할 수 있습니다. 아래와 같습니다.
var StringBuilder.lastChar: Char
    get() = get(length - 1)
    set(value: Char){
        this.setCharAt(length - 1, value)
    }

너는 아마도 처음에 이런 문법에 대해 좀 낯설었을 것이다. 괜찮아. 나중에 우리는 더 많은 관련 내용을 소개할 것이다.Kotlin과 Java에서 호출하는 방법을 살펴보겠습니다.
//Kotlin   
import expand.lastChar

fun main(args: Array<String>){
    val sb = StringBuilder("abc")
    sb.lastChar = 'M'
    println(sb)
    println(sb.lastChar)
}

사용하기 전에 반드시 가져오고 일반 속성처럼 사용하면 된다.
//Java   
import expand.ExpandFunKt;

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("BNM");
        ExpandFunKt.setLastChar(sb, 'W');
        System.out.println(ExpandFunKt.getLastChar(sb));
    }
}

자바에서 호출할 때 확장 속성 코드가 적힌 클래스를 가져오고, 인자를 전달할 때 확장된 클래스의 대상과 설정할 값을 가져와야 하며, 정적 함수처럼 geteer와setter 방법을 호출합니다.

맨 마지막에 쓰다


Kotlin의 확장 함수와 속성은 코드 디자인의 유연성을 증가시킨다. 우리는 기존 클래스를 바탕으로 확장과 수정을 하고 우리의 클래스를 맞춤형으로 만들 수 있다. 이것은 Kotlin의 자바의 상호작용을 크게 편리하게 한다.

좋은 웹페이지 즐겨찾기