Kotlin

[Kotlin] Constructor

hvoon 2022. 9. 14. 15:29

Kotlin은 클래스에 init 코드 블록을 만들어 주면 객체 생성 시 자동으로 처리되는 코드를 만들 수 있음. 멤버변수에 값을 초기화하는 기능도 가능.

init 블럭은 생성자와 비슷한 역할을 할 수 있는 영역이지만 전달인수나 기타의 함수로서의 기능은 없는 단순 블럭. init 블럭은 멤버변수 초기화, 생성자는 그 외 객체 생성 시 해야할 일들이 실행됨.

fun main(){
    val obj1 = TestClass11()
    println("obj1: $obj1")
}

class TestClass11(){
    init{
        println("객체가 생성되면 자동으로 동작되는 부분")
    }
}

fun main(){
    val obj2 = TestClass12() // 매개변수가 없는 생성자 호출
    println("obj2: ${obj2.v1}")
    println("obj2: ${obj2.v2}")
    val obj3 = TestClass12(300, 400) // 매개변수가 있는 생성자 호출
    println("obj3: $obj3")
    println("obj3: ${obj3.v1}")
    println("obj3: ${obj3.v2}")
}

class TestClass12{
    var v1:Int=0
    var v2:Int=0
    // 생성자를 만듦
    // 생성자를 만들지 않으면 내부에 존재하는 디폴트 생성자가 사용되지만
    // 인위적으로 꺼내서 따로 기술 가능
    // 코틀린 클래스의 생성자의 이름은 클래스이름을 따르지 않고 그냥 Constructor라고 사용함
    constructor(){
        println("매개변수가 없는 생성자")
        v1=100
        v2=200
    }
    // constructor라는 이름의 생성자는 오버로딩도 가능
    constructor(a1:Int, a2:Int){
        println("매개 변수가 두 개인 생성자")
        v1=a1
        v2=a2
    }
}

주(대표)생성자

- 자바에는 없는 클래스 이름 옆에 기술하는 생성자

- 그 외 클래스 내부에 만들어지는 다른 오버로딩된 생성자들은 보조 생성자라고 부름

- 주생성자에 매개변수들을 var, val 등을 붙여서 선언함. 이렇게 만들어진 생성자의 매개변수들은 매개변수이기도 하지만 "클래스의 멤버변수"가 되기도 함.

- 위 클래스 TestClass13의 이름 옆에 생성자는 매개변수가 없는 디폴트 생성자를 대체하는 생성자로서 매개변수 없는 생성자는 현재 클래스에서 없다고 생각해야 함. 디폴트 생성자를 추가해야 한다면 보조생성자로 오버로딩되게 생성함. 그 때 오버로딩되는 클래스 내부의 생성자는 보조 생성자라고 부름

fun main(){
    val obj4 = TestClass13(100, 200)
    println("obj4:a1: ${obj4.v1}")
    println("obj4:a2: ${obj4.v2}")
}
class TestClass13 constructor(var v1:Int, var v2:Int)
// 클래스 내용이 없을 때는 중괄호 생략 가능

// class TestClass13 constructor(){}
// 클래스 생성 시 매개변수가 없는 생성자는 이미 존재하기에 위와 같은 표현은 따로 쓰지 않음

 

fun main(){
    val obj5: TestClass15 = TestClass15(10, 20)
    val obj6: TestClass15 = TestClass15()
    val obj7: TestClass15 = TestClass15(100)

}

// 클래스 이름 옆에 대표 생성자를 만들고 나서 오버로딩된 다른 보조 생성자를 사용하고 싶을 때
class TestClass15 constructor(var v1:Int, var v2:Int){
    // 클래스의 이름 옆에 있는 대표생성자는 객체 생성 시에
    // '반드시 한번은 호출' 되어야하는 강제규칙이 있음
    // 이는 보조생성자가 있고 보조생성자가 호출되더라도 마찬가지
    // 만약 객체생성시에 보조생성자가 호출되었다면
    // 해당 보조생성자에서 대표생성자를 재호출해야 에러 안남
    // 보조 생성자에서 디폴트 생성자를 재호출하는 방법은
    // Constructor() 옆에: this(디폴트생성자에 맞는 전달인수) 형태로 호출함
    // 클래스 이름 옆에 대표생성자는 '멤버변수를 포함하고 있기 때문에' 그를 호출하지 않으면
    // 객체 생성 시 멤버변수가 만들어지지 않는다는 말과 같음
    // 따라서 반드시 this 호출이 필요함
    constructor(): this(10, 20){
        println("매개변수 없는 보조 생성자 호출")
    }
    constructor(a1:Int): this(10, 20){
        println("매개변수가 한개인 보조 생성자 호출")
    }
}
 

성적 출력

package days02

import java.text.DecimalFormat

fun main(){
    var std1 = Student()
    std1.kor = 70; std1.mat =70; std1.eng = 70
    std1.prnScore() // 이름, 각 과목 점수와 총점, 평균 출력
    // std1 학생 번호 1, 이름은 이름없음1

    var std2 = Student(1, "홍길동")
    std2.kor = 80; std2.mat =85; std2.eng = 90
    std2.prnScore()

    var std3 = Student(2, "홍길남", 50, 60, 80)
    std3.prnScore()
}

class Student constructor(var bun:Int, var name:String) {
    var kor:Int=0
    var eng:Int=0
    var mat:Int=0
    var tot:Int=0
    var ave:Double=0.0

    constructor(): this(1, "이름없음1") {
    }

    constructor(b:Int, n:String, k:Int, m:Int, e:Int):this(b, n){
        kor=k; mat=m; eng=e
    }

    fun prnScore(){
        tot= kor+eng+mat
        ave= tot/3.0
        println("번호: $bun, 성명: $name, 국어: $kor, 영어: $eng, 수학: $mat, 총점: $tot, 평균: $ave")
    }
}