코틀린 스터디 델리게이트

코틀린의 델리게이트

  1. class delegate - 앞에서 다루었던 property delegate와는 완전 다른 기법이다. - 밑의 코드는 class delegate를 사용한다. - 클래스에서 by의 위치는 상속받거나 implementation 하는 위치 다음에 by가 나온다. - by 뒤에 나오는 person은 class나 interface가 아니라 인스턴스(객체)가 나온다. - 그러면 Person이라는 인터페이스의 구현을 by 뒤의 인스턴스에게 위임을 한것임.

밑의 코드는 인자값으로 person으로 받아 Person 인터페이스 구현을 인자로 person 한태 처리하기로 한것 우리는 여기에 overide printName을 하지 않았음. 유저클래스에 보면 person을 상속했는데도 불구하고 overide printName을 안했음. 인터페이스는 상속한 곳에서 구현을 해야되는데 .안했다는 의미는 person 인스턴스의 person의 printName이 User의 printName을 대체했음.

interface Person {
    fun printName()
}

class PersonImpl(val name:String):Person {
    override fun printName() {
        println(name)
    }
}

class User(val person:Person):Person by person

    val person = PersonImpl("Mario Arias")
    val user = User(person)
    user.printName()

만약 위임했는데도 불구하고 override를 한다면 위임한 person의 PrintName이 아닌 User가 구현한 printName을 사용할 것임. 밑의 코드 참고

interface Person {
    fun printName()
}

class PersonImpl(val name:String):Person {
    override fun printName() {
        println(name)
    }
}

class User(val person:Person):Person by person {

    override fun printName() {
        println("Printing Name:")
        person.printName()
    }
}

밑의 코드와 같이 생성자에 속성으로 만들기 위해 val을 붙히는 것 말고도 생성자의 인자값(val이나 var을 제거)하고 들어와도 person은 by뒤에 붙힐 수 있다.

class User2(person:Person): Person by person

밑의 코드와 같이 인자값을 받아 인자값을 사용하여 인터페이스를 구현해서 그 클래스에 위임하는 클래스를 만들 수 있다. 밑의 패턴이 굉장히 많이 쓰인다.

class User5(v :String): Person by object:Person {
    override fun printName() {
        println("인자값을 받아 오브젝트 표현식으로 객체를 새로 만들기 받은 파라미터 : $v")
    }
}

한 클래스에 여러개의 인터페이스를 상속하고 위임할 경우 각각 by를 사용한다.

class User6(person:Person, people:People): Person by person, People by people

fun main() {
    val people = PeopleImpl("이태원 코딩도장 사람들")
    val person3 = PersonImpl("오야지")
    val user6 = User6(person3,people);
    user6.printName()
    user6.peopleName()
}

Written by@Zero1
This blog is for that I organize what I study and my thinking, feeling and experience.

GitHub