클래스는 객체를 생성하기 객체를 생성하기 위한 설계도(틀)이라고 할 수 있습니다.
클래스는 데이터를 담는 프로퍼티(멤버 변수),와 그 데이터를 다루는 함수(메서드)를 함께 정의할 수 있습니다.
클래스는 참조타입입니다.
이는 클래스의 인스턴스(객체)가 힙 메모리에 할당되며, 변수가 그 객체에 대한 참조(주소)를 저장한다는 의미입니다.
class Person(var name: String)
fun main() {
// Person 클래스의 인스턴스가 힙 메모리에 생성됩니다.
val person1 = Person("홍길동")
// person2는 person1이 가리키는 동일한 객체를 참조합니다.
val person2 = person1
// 참조 비교: person1과 person2는 같은 객체를 참조하므로 true
println("person1과 person2는 같은 객체인가요? ${person1 === person2}")
// person2의 name을 변경하면, 같은 객체를 참조하기 때문에 person1의 name도 변경
person2.name = "제임스"
println("person1의 name: ${person1.name}") // 출력: 제임스
}
kotlin 클래스는 기본 생성자와 선택적으로 하나 이상의 보조 생성자를 가질 수 있습니다.
기본 생성자는 클래스 헤더에 선언되며, 클래스 이름과 타입 매개변수 뒤에 위치합니다.
class Person constructor(firstName: String) {}
이 때 기본 생성자에 어노테이션이나 접근 제어자가 없다면, constructor 키워드를 생략할 수 있습니다.
class Person(firstName: String) {}
기본 생성자는 클래스 인스턴스를 초기화하며, 클래스 헤더에서 프로퍼티를 초기화 할 수 있습니다.
단, 클래스 헤더 안에서는 로직을 작성할 수 없습니다.
객체 생성 시 실행해야 하는 코드를 작성하려면 init 블록을 사용합니다
다음 코드의 실행 순서를 보겠습니다.
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints $name")
}
val secondProperty = "Second property: $(name.lenght)".also(::println)
init {
println("Second initializer block that print ${name.lenght})"
}
}
First property: hello
First initializer block that prints hello
Second property: 5
Second initializer block that prints 5
선언된 순서대로 실행됩니다.
만약 생성자에 어노테이션(@Inject)나 접근 제어자(public, private 등)가 붙는다면,
반드시 constructor 키워드를 명시해야 합니다.
class Customer public @Inject constructor(name: String) {}
클래스는 보조 생성자를 가질 수 있으며, 보조 생성자는 constructor 키워드로 시작합니다.
class Person(val name: String) {
val children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
Class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor $i")
}
}
Init block
Constructor 1
추상 클래스가 아닌 일반 클래스에서 기본 생성자나 보조 생성자를 하나도 선언하지 않으면, 컴파일러가 매개변수 없는 기본 생성자를 생성하며 이 생성자는 public 입니다.