# Table Of Contents

# 클래스에서의 this

클래스에서의 this는 해당 위치에서 가장 가까운 클래스의 인스턴스를 의미한다. 아래 예제를 살펴보자.






 



 





class Person {
    
    var name: String
    
    constructor(name: String) {
        this.name = name
    }
    
    fun printSomething() {
        println(this.name)
    }
}

val person = Person("Paul")

위 코드에서의 thisPerson클래스의 인스턴스를 의미한다. 키워드 this는 생략할 수 있다.






 
 



 
 





class Person {
    
    var name: String
    
    constructor(name: String) {
        // this.name = name
        name = name
    }
    
    fun printSomething() {
        // println(this.name)
        println(name)
    }
}

val person = Person("Paul")

# 확장 함수에서의 this

확장 함수에서의 this는 확장 함수를 호출한 클래스의 인스턴스를 의미한다. 다음과 같은 클래스가 있다고 가정하자.

class Person constructor(val name: String, val age: Int) {

    fun printName() {
        println("Name: ${this.name}")
    }

    fun printAge() {
        println("Age: ${this.age}")
    }
}

그 다음 확장 함수를 추가해보자.

fun Person.printInformation() {
    print("${this.name} is ${this.age} years old.")
}

확장 함수에서 this점(.)의 왼쪽에 위치하는 확장 함수를 호출한 클래스 (예제에서는 Person클래스의 인스턴스)를 의미한다.

# 스코프 함수에서의 this

스코프 함수에서의 this는 리시버를 의미한다. 리시버(Receiver)는 스코프 호출을 호출한, 점(.)의 왼쪽에 위치하는 대상이다.

우선 스코프 함수 run() 예제를 살펴봅시다.

class Person constructor(var name: String, var age: Int) {

}

val person = Person("Paul", 35)

// 스코프 함수
person.run {
    // this는 person을 의미
    this.name = "John"
    this.age = 33
    println("His name is ${this.name}")
}

스코프 함수 with()의 예제도 살펴봅시다.

class Person constructor(var name: String, var age: Int) {

}

val person = Person("Paul", 35)

// 스코프 함수
with(person) {
    // this는 person을 의미
    this.name = "John"
    this.age = 35
    println("His name is ${this.name}")
}

# Qualified this

아래 코드를 살펴봅시다. 클래스 안에 내부 클래스가 있고, 내부 클래스 안에 확장 함수가 있다.

class Outer {
    inner class Inner {
        fun Int.multiple(a: Int, b: Int): Int {
            return a*b
        }
    }
}

이때 확장 함수에서의 this는 무엇을 가리킬까?

class Outer {
    
    inner class Inner {
        fun Int.multiple(a: Int, b: Int): Int {
            val what = this     // this는 무엇을 가리킬까?
            return a*b
        }
    }
}

확장 함수에서의 this는 확장 함수를 호출하는 리시버인 Int다.

그럼 확장 함수 안에서 Outer클래스와 Inner클래스는 어떻게 접근할 수 있을까? 이러한 경우에 Qualifed this를 사용하면 된다. Qualifed thisthis@클래스이름 형태로 사용한다.

class Outer {
    
    inner class Inner {
        fun Int.multiple(a: Int, b: Int): Int {
            val what = this         // Int
            val inner = this@Inner  // Inner
            val outer = this@Outer  // Outer
            return a*b
        }
    }
}

아래 코드는 안드로이드에서 자주 사용하는 패턴으로 버튼을 눌렀을 때 특정 로직을 수행하는 코드다.

class MainActivity: AppCompatActivity() {

    lateinit var buttonSayHello: Button

    override fun onCreate(saveInstanceState: Bundle?) {
        super.onCreate(saveInstanceState)

        buttonSayHello = findViewById(R.id.activity_main_button_say_hello) as Button

        buttonSayHello.setOnClickListener(object: View.OnClickListener {
            override fun onClick(view: View) {
                Toast.makeText(this@MainActivity, "Hello", Toast.LENGTH_SHORT).show()
            }
        })
    }
}

onClick()메소드 안에서의 thisView.OnClickListener를 가리킨다. 따라서 액티비티의 인스턴스를 참조하기 위해 this@MyActivity를 사용한다.