연습장/이론

클래스 6-1. object

아이른 2024. 5. 6. 19:57

1. object

1-1. Object Expression (aka Anonymous Class - 익명(이름이 없는) 클래스)

  • 단 하나의 인스턴스를 가짐
data class User(
    val name: String,
    val age: Int,
    var isStrong: Boolean
)
fun main() {
    // Object Expression
    val spartan = object {
        val name = "Spartan"
        val age = 100
        var isStrong= true
    }

    println(spartan.name) //Spartan
    println(spartan.age) //100

    repeat(3){
        println(spartan.hashCode())
    }
    /* 같은 주소값 출력 = 위의 객체는 전부 같음
    985465781
    985465781
    985465781
    */
    
    spartan.isStrong = false
    println(spartan.isStrong) //false

    repeat(3){
        println(spartan.hashCode())
    }
    /* isStrong 값을 변경하여도 같은 주소값 출력
    985465781
    985465781
    985465781
    */
  • 잘못된 사용
data class User(
    val name: String,
    val age: Int,
    var isStrong: Boolean
)
fun main() {
    val spartan = object {
        val name = "Spartan"
        val age = 100
        var isStrong= true
    }

    val user = User(name="user", age=10, isStrong = false)
    repeat(3){
        println(user.hashCode())
    }
    /* 하나의 객체이기 때문에 주소값 같음
    836431855
    836431855
    836431855
    */
    
    val newUser = user
    newUser.isStrong = true
    repeat(3){
        println(newUser.hashCode())
    }
    /* 안에 있는 값이 달라지기 때문에 주소값이 다름
    836542533
    836542533
    836542533
    */
    
    println(user == newUser)
    /*
    true 
    주소값은 다른데 true가 출력
    data class 작성 시, var을 통해 중간의 값을 변경하면 안됨
    */

    val anotherUser = user.copy(isStrong = false)
    //방어적 복사를 통해 사용
    println(user == anotherUser)
    //false
}

1-2. capturing, closure

  • capturing, closure : object expression 내부에서 외부에 있는 변수를 변경
    var a = 10
    //object expression
    button.setOnClickListener(object : OnClickListener {
        override fun onClick(v: View) {
            a = 11 //capturing, closure
            /*
            capturing, closure 시, 한번 쓰여지고 버려짐
            : 익명의 클래스이기 때문에 한번 쓰여지면 object에 접근을 하려해도 
            이름이 없기 때문에 이후에 접근을 하지 못함
            */
        }
    })
    
    //람다로 간단하게 사용하고 있었던 것
    button.setOnClickListener {
    }
    //매번 새로운 OnClickListener object가 생성

1-3. Object declaration

  • Singleton : object로 만들면 앱이 돌아가는 동안 하나의 인스턴스만 메모리에 있음
object Spartan {
    val name = "Spartan"
    val age = 100
    val isStrong = true
}
  • Companion objects : 외부에는 노출시키고 싶지 않지만 외부에서 해당 객체를 원할 때 사용
class President {
    private var name="onlyOne"

/*    fun create(): President{
        return President(name = "Hongkildong")
    }*/

    companion object { //President 내부에 있기 때문에 private 접근o
        fun create() : President {
            val president = President()
            president.name = "New Guy"
            return president
        }
    }

    override fun toString(): String {
        return this.name
    }
}

fun main(){
    val president = President()
     //println(president.name): private이기 때문에 name에 접근x

    val newPresident = President.create()
    println(newPresident.toString()) //New Guy

    val fakePresident = President.Companion.create()
    println(fakePresident.toString()) //New Guy
}
  • Top-level constants vs Companion objects
const val AA = "AA" //어디서든 접근 가능

internal class B { //같은 모듈 안에서만 가능
    companion object{
        const val BB = "BB"
    }
}

fun main() {
    println(AA) //AA
    println(B.BB) //BB
}