[코틀린기초] 29. 정적 변수와 컴페니언 객체

정적이란 메모리에 딱 생성되어 고정되어있는 것.

보통 클래스는 동적으로 객체를 생성하는데 정적으로 고정하는 방법은?

#### 컴패니언 객체는 실제 객체의 싱글톤으로 정의됨 -> 객체를 여러개 생성해도 컴페니언 객체는 단 하나!

  class Person{
    var id: Int = 0
    var name: String = "Youngdeok"
    
    companion object{ // 고정된 static 내부 클래스처럼 정의 된다.
      var language: String = "Korean"
      fun work(){
        println("working...")
      }
    }
  }
  
  fun main(){
    println(Person.language)  // 인스턴스 생성 없이 기본 값 사용
    Person.language = "English" // 기본 값 접근 가능
    println(Person.language)    // 변경된 내용 출력
    Person.work()             //  메서드 실행
    //println(Person.name)  //  name은 컴페니언 객체가 아니므로 에러!
  }

## 자바에서 코틀린 컴패니언 객체 사용하기

  //KCustomer.kt
  
  class KCustomer{
    companion object{
      const val LEVEL ="INTERMEDIATE" //  const 와 val을 함께 사용하면, 컴파일 시간에 값이 결정됨
      @JvmStatic fun login() = println("Login...")  //  애너테이션 사용
 
    }
  }
 
 // KCustomerAccess.java
 
  public class KCostomerAccess{
    public static void main(String[] args){
      System.out.println(KCustomer.LEVEL)
      KCustomer.login();  //  애너테이션을 사용할 때 접근 법
      KCustomer.Companion.login();  // 위와 동일한 결과로 애너테이션을 사용하지 않을 때 접근법
    }
  }

## 최상위 함수 정리

### 자바에서 코틀린의 최상위 함수 접근

  //PackageLevelFuncion.kt
  
  @file:JvmName("PKLevel")  // 변환되는 클래스 명을 명시적으로 지정
  
  fun packageLevelFunc(){
    println("Package-Level Function")
  }
  
  fun main(){
    packageLevelFunc()
  }
  
  
  // PackageLevelAccess.java
  
  public class PackageLevelAccess{
    public static void main(String[] args){
      PKLevel.packageLevelFunc(); //  명시적으로 지정한 클래스 명 사용
    }
  }
  

## object와 싱글톤

  object OCustomer{
    var name = "Kildong"
    fun greeting() = println("Hello world!")
    val HOBBY = Hobby("Basketball")
    init{
      println("Init!")
    }
  }
  
  class Hobby(val name: String)
  
  fun main(){
    OCustomer.greeting()  // 객체의 접근 시점
    OCustomer.name = "Dooly"
    println("name = ${OCustomer.name}")
    println(OCustomer.HOBBY.name)
  }

### object 표현식

  open class Superman(){
    fun work() = println("Taking photos")
    fun talk() = println("Talking with people")
    open fun fly() = println("Fly")
  }
  
  fun main(){
    val pretendedMan = object: Superman(){  // object 표현식으로 fly() 구현 재정의
      override fun fly() = println("I'm nor a real superman")
    }
    
    pretendedMan.work()
    pretendedMan.talk()
    pretendedMan.fly()
  }