좌충우돌 코딩

코틀린 - 클래스(class) 본문

코틀린/순수 코틀린

코틀린 - 클래스(class)

Tracoding 2023. 3. 24. 23:57

클래스는 간단히 생각해서 틀이라고 생각하면 됩니다.

달고나를 만들고 나면 모양을 만드는 틀처럼 말이죠.

 

class User {
	// 코드
}

위와 같은 상태로 선언을 할 수 있습니다.

클래스명은 첫글자는 대문자로 하는 것이 코딩컨벤션입니다.

 

val user = User()

변수에 클래스를 할당하는 것을 인스턴스 생성이라고 합니다.

쉽게 생각하면 변수에 클래스를 마구마구 넣어서 찍어낼 수 있으니까요.

주 생성자(Primary Constructor)

class User(name: String) {
	// 코드
}

생성자는 클래스 이름 옆에 있는 괄호를 생성자라 부릅니다.

원래는 constructor가 생략된 것입니다.

 

class User constructor(name: String) // constructor 사용

class User(name: String) // constructor 생략

위와 같이 사용할 수 있습니다.

아무래도 두번째가 간략하고 편해서 자주 사용하겠죠.

 

 

// 클래스 생성자 생성
class User(name: String) {
    init {
        println("당신의 이름은 ${name}입니다")
    }
}

// 인스턴스 생성
val user = User("코틀린")  // 이름은 코틀린입니다 출력됨

인스턴스를 생성하면 아무것도 안했는데 콘솔에 "이름은 코틀린입니다"가 출력되는 것을 볼 수 있습니다.

그 이유는 클래스에서 init를 사용했기 때문이죠.

 

init는 인스턴스를 생성하면 무조건 호출이 되며, init 초기화에 많이 사용을 합니다.

 

class User(val name: String)

생성자 파라미터 앞에 val를 붙여주면 클래스 스코프 내부 전역에서 사용이 가능합니다.

물론 var도 사용이 가능합니다. 

 

// 첫번째 클래스
class User1(name: String) {
    fun myName() {
        println("이름: ${name}")
    }
}

// 두번째 클래스
class User2(val name: String) {
    fun myName() {
        println("이름: ${name}")
    }
}

User1 클래스와 User2 클래스가 있습니다.

두 개의 클래스 모두 myName이라는 함수를 가지고 있는데, 하나는 오류가 발생하는 클래스입니다.

 

당연하 위에서 설명했듯이 User1 클래스에서 오류가 발생합니다.

함수 안에 ${name}를 참조하지 못한다는 에러죠.

 

생성자에 val 또는 var를 안 쓰고 전역 변수로 사용할 수 있는 방법이 있습니다.

class User(name: String, age: Int) {
    var name = name
    var age = age

    fun myName() {
        println("이름: ${name}, 나이: ${age}")
    }
}

위와 같이 클래스 안에 변수를 초기화 해주면 됩니다.

 

부 생성자(Secondary Constructor)

constructor는 클래스 내부에서도 사용이 가능합니다.

만일 내부에 constructor를 사용하게 되면 부 생성자라고 부르죠.

부 생성자는 주 생성자와 다르게 constructor를 생략할 수 없습니다.

class User(name: String) {
    var age = 20

//    에러 발생
//    constructor(name: String, age: Int) {
//        this.age = age
//    }

    constructor(name: String, age: Int) : this(name) {
        this.age = age
    }
}

첫번째 부 생성자에 주석에는 에러 발생이라고 되어있죠?

그 이유는 부 생성자는 무조건 주 생성자를 통해서 생성을 해야하기 때문입니다.

 

name과 age를 가지고 있는 생성자를 생성하기 위해서는 부생성자가 this(name)에게 생성을 위임한 것이라 보면 됩니다.

그래서 첫번째 부 생성자는 this(name)가 없기 때문에 에러가 발생하는 것이죠.

 

주 생성자는 name을 가지고 있고 주 생성자의 부하가 this(name)이라고 생각하면 됩니다.

그래서 부 생성자는 name과 age를 갖는 생성자를 만들기 위해선 주 생성자의 권한이 필요하기 때문에 this(name)을 통해

생성자를 만드는 것이고 이러한 현상을 보고 부 생성자는 무조건 주 생성자를 통해서 생성된다고 하는 것입니다.

 

 

클래스 내부 호출 순서

부 생성자와 init 순서를 알아볼까요?

class SpeedTest(car: String) {
    var speed = 20
    var power = 100

    constructor(car: String, speed: Int) : this(car) {
        this.speed = speed
        println("call constructor(car, speed)")
    }
    
    constructor(car: String, speed: Int, power: Int) : this(car, speed) {
        this.power = power
        println("call constructor(car, speed, power)")
    }

    init {
        println("call init")
    }
}

// 인스턴스 생성
var speedTest = SpeedTest("Test", 100, 500)

자! 승자는 누가 될까요???

 

두둥탁!!

init가 가장 먼저 호출이 되었습니다.

 

그 다음 car와 speed를 가진 생성자가 호출 되었고 마지막으로 power까지 가진 생성자가 마지막으로 호출이 되었습니다.

코딩 순서의 상관없이 무조건 init가 가장 먼저 호출이 되고 그 다음 처음으로 주 생성자에게 생성을 위임한 부생성자가 

호출 됩니다. 그 다음은 당연히 부 생성자에게 생성을 위임한 부 생성자가 호출 되는 것이죠.

 

init

=> 가장 먼저 호출

 

constructor(car: String, speed: Int) : this(car)

=> 두번째로 호출, 주 생성자에게 생성 위임.

 

constructor(car: String, speed: Int, power: Int) : this(car, speed)

=> 세번째로 호출, 부 생성자에게 생성 위임 / this(car, speed) 부 생성자는 this(car) 주 생성자에게 위임

 

위와 같은 방식이기 때문에 코딩 순서를 변경한다고 해도 동일한 결과가 나옵니다.

그럼 파라미터 값은 어떻게 나올까요??

var speedTest = SpeedTest("Test", 100, 500)
init {
    println("init ${car}, ${speed}, ${power}")  // init test, 20, 100 출력됨
}
 constructor(car: String, speed: Int) : this(car) {
    this.speed = speed
    println("constructor(car, speed) ${car}, ${speed}") //  constructor(car, speed) test 100 출력됨 
}
constructor(car: String, speed: Int, power: Int) : this(car, speed) {
    this.power = power
    println("constructor(car, speed, power) ${car}, ${speed}, ${power}")
    // constructor(car, speed, power) test 100 200 출력됨
}

 

 

 

저는 이만~

'코틀린 > 순수 코틀린' 카테고리의 다른 글

코틀린 - 상속  (0) 2023.03.26
코틀린 - 접근제한자  (0) 2023.03.25
코틀린 - 함수(funcation)  (0) 2023.03.23
코틀린 - 반복문(for, while)  (0) 2023.03.22
코틀린 - 컬렉션(Collection)  (0) 2023.03.21
Comments