1. 클래스 선언방법-1 : 클래스 헤더가 존재하지 않는 형태 - 클래스 헤더는 매개변수나 기본 생성자를 의미합니다. 이를 사용하지 않은 클래스를 선언하는 예시입니다.
2. 클래스 선언 방법-2: 클래스 헤더(매개변수)가 존재하는 경우 - 클래스 헤더로 매개변수를 받는 경우를 의미합니다. 즉, 인스턴스화 할때, 필수로 매개변수로 id, name 값을 받는 클래스를 선언하는 예시입니다. 3. 클래스 선언 방법-3: 본문이 없는 경우 - 클래스로 선언하였지만, 본문에 내용이 없는 경우를 의미합니다. 이는 향후 확장을 위한 자리 표시자로 사용될 수 있습니다.
// 클래스 선언 방법-1: 클래스 헤더가 존재하지 않는 형태classPerson {
// 클래스 본문var name: String = ""var age: Int = 0
}
// 클래스 선언 방법-2: 클래스 헤더(매개변수)가 존재하는 경우classStudent(privateval id: Int, privatevar name: String) {
// 클래스 본문funintroduce() {
println("My name is $name and my student ID is $id")
}
}
// 클래스 선언 방법-3: 본문이 없는 경우classEmptyClass;
💡 생성자 선언 방법 1. 생성자 선언 방법-1: 클래스 이름과 매개변수 뒤에 constructor 선언하는 경우 - 클래스 구성 시 ‘constructor’를 통해서 생성자도 함께 생성하는 경우를 의미합니다. 2. 생성자 선언 방법-2: constructor를 사용하지 않는 경우 - 해당 경우에서는 매개변수들은 자동으로 클래스의 주 생성자가 됩니다.이 방식으로 선언된 매개변수들은 클래스 내부에서 사용할 수 있지만, 자동으로 프로퍼티가 되지는 않습니다. 3. 생성자 선언 방법-3 : 주 생성자와 보조 생성자가 존재하는 경우 - 해당 경우에서는 name, age라는 값을 이용하여 주 생성자를 구성하였습니다. - 클래스 본문 내에서 constructor를 통해서 name의 값은 필수 매개변수로 받으면서, age라는 매개변수에 대해서는 0으로 초기화를 하여 선택적으로 인스턴스화 할 수 있도록 구성합니다.
package com.blog.kotlinspringbootform.component
// 생성자 선언 방법-1: 클래스 이름과 매개변수 뒤에 constructor 선언하는 경우classConstructorComponentconstructor(firstName: String) {
init {
// 생성자 초기화 수행
}
}
// 생성자 선언 방법-2: constructor를 사용하지 않는 경우classConstructorComponent(firstName: String, lastName: String, age: Int) {
init {
// 생성자 초기화 수행
}
}
// 생성자 선언 방법-3 : 주 생성자와 보조 생성자가 존재하는 경우classPerson(val name: String, var age: Int) {
// 주 생성자init {
// 생성자 초기화 수행
}
constructor(name: String) : this(name, 0) {
// 보조 생성자
}
}
// 아래와 같은 구조를 통해 객체 생성 시 유연성을 제공합니다.val person1 = Person("Alice", 30) // 주 생성자 사용val person2 = Person("Bob") // 보조 생성자 사용, age는 0으로 초기화됨
- 클래스의 초기화 코드를 포함하는 특별한 블록을 의미합니다. - 주 생성자의 일부로 실행되며, 클래스가 인스턴스화될 때 호출됩니다. - 클래스 내에 여러 init 블록을 가질 수 있으며, 이들은 클래스 본문에 나타나는 순서대로 실행됩니다.
특징
설명
초기화 순서
클래스 본문에 나타나는 순서대로 실행됩니다.
주 생성자와의 관계
주 생성자의 일부로 실행되며, 주 생성자 매개변수에 접근할 수 있습니다.
다중 사용
하나의 클래스에 여러 init 블록을 정의할 수 있습니다.
프로퍼티 초기화
프로퍼티 초기화와 교차적으로 실행됩니다.
예외 처리
초기화 중 예외를 던질 수 있어 객체 생성 실패를 명시적으로 처리할 수 있습니다.
classPerson(val name: String) {
var age: Int = 0init {
println("Person instance created with name: $name")
}
init {
println("This is the second init block")
}
}
// 사용 예val person = Person("Alice")
// 출력:// Person instance created with name: Alice// This is the second init block
- 클래스는 프로퍼티를 가질 수 있으며, 이는 주 생성자에서 선언하거나 클래스 본문에서 선언할 수 있습니다. - 해당 프로퍼티는 Java의 멤버 변수와 다르게 getter, setter를 자동으로 생성합니다. - val로 생성한 프로퍼티는 읽기전용으로 gettter가 되지만, var로 생성한 프로퍼티는 getter/setter로 읽기 쓰기가 가능합니다.
💡 프로퍼티 예시
- Person 클래스 내에 email 이라는 프로퍼티를 클래스 내에 선언하였습니다.
classPerson(val name: String, var age: Int) {
var email: String = ""
}
- 프로퍼티는 Kotlin의 개념으로, getter와 setter를 자동으로 생성합니다. - 멤버 변수는 Java의 개념으로, 단순히 클래스 내부의 변수를 의미합니다. - 따라서, Kotlin의 프로퍼티는 멤버 변수의 개념을 포함하면서도 더 확장된 기능을 제공한다고 볼 수 있습니다.
classPerson(val name: String, var age: Int) {
// 메서드 선언부funintroduce() {
println("My name is $name and I'm $age years old.")
}
}
// Person 클래스의 인스턴스 생성val person = Person("Alice", 30)
// introduce 메서드 호출 : My name is Alice and I'm 30 years old. 출력
person.introduce()
- Animal 클래스 내에서 ‘open’ 키워드를 두어서 외부에서 상속하는것에 대해서 허용합니다. 즉, Dog 클래스 기준으로 Animal 클래스로 부터 상속을 받습니다. - 이를 상속받은 Dog 클래스 내에서는 Anmal 클래스의 makeSound() 메서드를 오버라이딩 합니다
openclassAnimal(val name: String) {
openfunmakeSound() {
println("The animal makes a sound")
}
}
classDog(name: String) : Animal(name) {
overridefunmakeSound() {
println("The dog barks")
}
}
- Kotlin은 데이터를 보유하는 목적의 클래스를 위한 특별한 'data class'를 제공합니다. - 일반적으로 구성하는 VO, DTO에 대한 정의를 위함입니다.
특징
설명
자동 생성 메서드
컴파일러가 자동으로 equals(), hashCode(), toString(), copy() 메서드를 생성. 코드 작성 시간 절약 및 오류 가능성 감소.
불변성 지원
주 생성자에서 프로퍼티를 val로 선언하여 불변 객체를 쉽게 생성 가능.
구조 분해
데이터 클래스 객체를 쉽게 구조 분해하여 여러 변수에 객체의 프로퍼티 할당 가능.
간결한 문법
최소한의 코드로 데이터 모델을 정의하여 코드의 가독성 향상.
💡 data class 사용예시
- 아래와 같이 data 클래스로 구성을 하는 경우, 별도의 getter/setter/toString 구성 없이도 접근이 가능합니다.
package com.blog.kotlinspringbootform.dto
dataclassUserDto(
val userSq: Int, // 사용자 시퀀스val userId: String, // 사용자 아이디val userPw: String, // 사용자 패스워드val userNm: String, // 사용자 이름val userSt: String, // 사용자 상태
)
💡 data class 호출 예시
- 타입을 UserDto로 지정한 user를 생성하여 data 클래스를 호출합니다. - UserDto의 파라미터를 통해서 각각의 값에 대해서 setter를 구성합니다. - userDto 객체의 프로퍼티에 접근하여 호출을 합니다. - userDto.toString() 메서드를 통해서 객체를 직렬화하여 호출합니다.
[더 알아보기] 💡 Kotlin에서는 Builder 패턴을 사용하지 않는가? - Kotlin에서는 일반적으로 Builder 패턴을 직접적으로 사용하지 않습니다. - Kotlin의 언어 기능들이 Builder 패턴의 장점을 대체할 수 있기 때문입니다. - 그러나 복잡한 객체 생성 로직이 필요한 경우는 Builder 패턴을 이용하여 구현합니다.
💡 [참고] 아래와 같은 형태로 Builder 패턴을 대체하여 사용합니다.
dataclassPerson(
val name: String,
val age: Int = 0,
val email: String? = null
)
// 사용 예val person = Person(
name = "John",
age = 30,
email = "john@example.com"
)
- ClassComponent 라는 클래스 내에서 내부 클래스로 InnerClass를 생성했습니다. 이 생성된 클래스는 함수내에서 호출이 가능합니다. - outer라는 변수에 인스턴스를 생성하고, inner라는 변수에 내부 클래스를 호출하도록 구성하였습니다. - 최종적으로 내부 클래스의 메서드에 접근하여서 호출을 하여 “Hello from Outer” 라는 콘솔에 출력을 하였습니다.
@ComponentclassClassComponent() {
privateval message: String = "Hello from Outer"innerclassInnerClass {
fungreet() = println(message)
}
/**
* 내부 클래스 호출 사용예시
*/funinnerClassCall() {
val outer = ClassComponent()
valinner = outer.InnerClass()
inner.greet() // 출력: Hello from Outer
}
}