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")
}
}