Kotlin에서 Class 선언 하는 방법에 대해서 포스팅을 했으니

Kotlin에서 Class 선언하기

 

Kotlin에서 Class 선언하기

Kotlin(코틀린)은 JetBrains에서 제작된 프로그래밍 언어로서 구글에서 Android 기본 언어로 채택 되면서 주목받는 hot한 언어가 되었다. JetBrains의 연구소가 있는 러시아 상트페테르부르크에 있는 코틀린 섬에..

ijeee.tistory.com

이번에는 Class 생성자(Constructor)에 대해서 포스팅 해보겠다.

 

Kotlin의 생성자는 주생성자(Primary Constructor)와 부생성자(Secondary Constructor)로 구분된다.

 

1. 주생성자

Kotlin을 배우면서 느낀점은 Java 개발자가 개발하면서 느꼈던 온갖 귀찮은 작업을 생략하는 언어라는 느낌이다-_-);;;

귀찮은 Java 개발자의 언어랄까......

 

 

Java에서는 모든 생성자는 method처럼 선언을 해주어야 한다 하지만 Kotlin에서는 그런 귀찮은 일을 하지 않아도 된다!!

주생성자는 class 선언하면서 생성자를 동시에 정의할 수 있는 기법이다.

방법은 class 이름 옆에 생성자의 parameter를 받고, Property 선언시

해당 값을 이용하여 초기화 해주면 된다.

 

class Animal(_nLeg:Int, _color:String) {
    val nLeg:Int = _nLeg
    val color:String = _color
    var name:String = "Tom"

    fun eat(something:String) {
        println("Eat $something")
    }

    fun cry() {
        println("Cry!!!")
    }
}

이제 Class를 사용하려면 아래와 같이 주생성자의 인자를 넘겨주어야 한다.

val myAnimal = Animal(4, "yellow")

자 이제 귀찮은 Java 개발자를 위해 한번더 생략!

생성자의 인자도 선언해줘야 하고 Property도 선언해줘야 하는데, 귀찮으니 한방에 쓰자!!!

 

생성자의 인자를 적어줄때 val, var을 적으면, 해당 인자가 바로 class의 property가 된다.

이 글을 보는 사람이라면 알겠지만 val은 불변, var은 변화가 가능한 Property

class Animal(val nLeg:Int, val color:String) {
    var name:String = "Tom"

    fun eat(something:String) {
        println("Eat $something")
    }

    fun cry() {
        println("Cry!!!")
    }
}

예제에서 보다시피 생성자를 통해서 초기화 하기 싫은 변수는 주생성자의 인자로 넣지 않고 따로 선언할 수 있다.

그런데 실제 개발을 하다보면 생성자에서 변수 초기화만 하지 않고 뭔가 로직을 넣어야 하는 상황이 오는데,

주생성자가 Class이름과 함께 정의를 하게된다면...

로직은 어떻게 넣을까???

 

Kotlin에서는 주생성자의 추가 로직을 위해 init이라고 하는 키워드를 통해 초기화 블록을 제공한다.

class Animal(val nLeg:Int, val color:String) {
    var name:String = "Tom"
    init {
        println("=== Primary Init block ===")
        println("nLeg: $nLeg, color: $color, name: $name")
        // Do something!!
    }

    fun eat(something:String) {
        println("Eat $something")
    }

    fun cry() {
        println("Cry!!!")
    }
}

 

2. 부생성자

부생성자는 Java의 생성자와 유사하다. 여러개의 생성자를 만들수 있고 생성자에서 어떤 동작을 할지 정의를 해주어야 한다.  부 생성자임을 알려주는 키워드는 constructor

단, 부생성자는 반드시 주생성자와 같이 사용되어야 한다. 부생성자는 주생성자를 호출한다.

class Animal(val nLeg:Int, val color:String) {
    var name:String = "Tom"
    init {
        println("=== Primary Init block ===")
        println("nLeg: $nLeg, color: $color, name: $name")
        // Do something!!
    }

    constructor(_nLeg:Int, _color:String, _name:String) : this(_nLeg, _color) {
        println("=== Secondary constructor start ===")
        this.name = _name
        println("=== Secondary constructor end ===")
    }

    fun eat(something:String) {
        println("Eat $something")
    }

    fun cry() {
        println("Cry!!!")
    }
}

부생성자 선언 뒤에 : this()를 통해서 주생성자의 인자를 전달해주어야 한다.

부생성자를 호출하게 되면 주생성자와 초기화 블록의 순서는 어떻게 될까??

val myAnimal = Animal(4, "yellow", "Smith")

 

=== Primary Init block ===
nLeg: 4, color: yellow, name: Tom
=== Secondary constructor start ===
=== Secondary constructor end ===

실행 결과에서 알수 있듯이 주생성자 -> 초기화 블록 -> 부생성자 순서로 호출된다.

 

포스팅에 사용된 소스는 아래의 github에서 확인 가능하다.

 

https://github.com/jeng832/blog-example/tree/master/24_Kotlin%20class%20constructor%20%EC%A0%95%EB%A6%AC

IntelliJ에서 Kotlin으로 작성된 소스를 Java 코드로 확인할 수 있다.

Decompiler 기능을 이용한 것인데..

 

Tools > Kotlin > Show Kotlin Bytecode 선택

Kotlin Bytecode 탭(?)에서 Decompile 버튼 클릭

 

Decompile 된 java 소스 확인

Kotlin(코틀린)은 JetBrains에서 제작된 프로그래밍 언어로서 구글에서 Android 기본 언어로 채택 되면서 주목받는 hot한 언어가 되었다.

JetBrains의 연구소가 있는 러시아 상트페테르부르크에 있는 코틀린 섬에서 이름을 따왔다고 한다...

 

본 포스팅에서는 Kotlin에서 Class를 만들고 상속받고 사용하는 방법에 대해서 기술하도록 한다.

 

먼저 가장 간단하게 Class 만들기

class Animal

중괄호도 필요 없다. 내용은 비었지만-_- 어쨌건 class 는 class다.

 

그렇다면 Class 사용하는 방법은?

val myAnimal = Animal()

new가 필요 없는 것에 주목.. Kotlin은 class 생성시 new 키워드를 사용하지 않는다.

 

내용이 비었으니 이제 내용을 채워보자. 

Class는 Class 이름, Attribute(member 변수, Property)와 Operation(method)로 구성된다.

 

먼저 Property를 추가...(Kotlin에서는 Attribute를 Property라고 부른다)

다리갯수(nLeg)와 색깔(color)를 추가하며, type 은 nLeg는 Int, color는 String으로 선언한다.

class Animal {
    val nLeg:Int = 4
    val color:String = "yellow"
}

 

Kotlin에서는 class에 기본 getter/setter를 만들어줄 필요가 없다.

val myAnimal = Animal()

println("Number of Leg is ${myAnimal.nLeg}")
println("Color is ${myAnimal.color}")

실행결과는?

Number of Leg is 4
Color is yellow

 

 

IntelliJ에서 Kotlin으로 개발을 하게 되면 Decompiler라는 기능을 통해서 Java로 변경된 code를 확인할 수 있는데, Class에 member만 추가하고 getter/setter가 없어도, Decompiler상에서는 getter/setter가 생성이 된다. 단, val로 선언된 변수의 경우 getter만 생성된다..

Decompiler를 실행하는 방법은 아래 포스팅 참조...

IntelliJ에서 Decompiler를 이용하여 Kotlin을 Java code로 확인하기

 

 

public final class Animal {
   private final int nLeg = 4;
   @NotNull
   private final String color = "yellow";

   public final int getNLeg() {
      return this.nLeg;
   }

   @NotNull
   public final String getColor() {
      return this.color;
   }
}

Property가 변경가능 한 값이면 val 대신 var로 선언해주면 된다.

class Animal() {
    val nLeg:Int = 4
    val color:String = "yellow"
    var name:String = "Tom"
}

 

&아래와 같이 {class 변수 이름}.{property 이름} 으로 접근하고 수정 가능

val myAnimal = Animal()

println("Name of the Animal is ${myAnimal.name}")
myAnimal.name = "Smith"
println("Name of the Animal is ${myAnimal.name}")

실행결과

Name of the Animal is Tom
Name of the Animal is Smith

 

 

 

이번에는 method를 추가해 보자

Anmial Class에 eat()와 cry() method를 추가 한다.

class Animal() {
    val nLeg:Int = 4
    val color:String = "yellow"
    var name:String = "Tom"

    fun eat(something:String) {
        println("Eat $something")
    }

    fun cry() {
        println("Cry!!!")
    }
}

확인해보면...

val myAnimal = Animal()

myAnimal.cry()
myAnimal.eat("apple")
Cry!!!
Eat apple

 

 

본 포스팅의 소스는 아래 github에서 확인 가능하다

https://github.com/jeng832/blog-example/tree/master/21_Kotlin%EC%97%90%EC%84%9C%20Class%20%EC%84%A0%EC%96%B8%ED%95%98%EA%B8%B0

+ Recent posts