클래스 (Classes)
코틀린은 클래스와 객체를 사용하여 객체 지향 프로그래밍을 지원합니다. 객체는 프로그램 내에서 데이터를 저장하는 데 유용합니다. 클래스를 사용하면 객체의 특성 집합을 선언할 수 있습니다. 클래스에서 객체를 생성할 때 이러한 특성을 매번 선언할 필요가 없으므로 시간과 노력을 절약할 수 있습니다.
클래스를 선언하려면 class 키워드를 사용하십시오.
class Customer
프로퍼티 (Properties)
클래스의 객체의 특성은 프로퍼티로 선언될 수 있습니다. 클래스에 대한 프로퍼티를 선언하는 방법은 다음과 같습니다:
- 클래스 이름 뒤의 괄호 () 내부에서 선언합니다.
class Contact(val id: Int, var email: String)
- 중괄호 {}로 정의된 클래스 본문 내부에서 선언합니다.
class Contact(val id: Int, var email: String) {
val category: String = ""
}
인스턴스가 생성된 후에 변경해야하는 경우를 제외하고는 프로퍼티를 읽기 전용 (val)으로 선언하는 것이 좋습니다.
괄호 내에서 val 또는 var 없이 프로퍼티를 선언할 수 있지만, 이러한 프로퍼티는 인스턴스가 생성된 후에 접근할 수 없습니다.
- 괄호 () 내부에 포함된 내용을 클래스 헤더라고 합니다.
- 클래스 프로퍼티를 선언할 때 후행 쉼표를 사용할 수 있습니다.
함수 매개변수와 마찬가지로 클래스 프로퍼티에는 기본값을 지정할 수 있습니다:
class Contact(val id: Int, var email: String = "example@gmail.com") {
val category: String = "work"
}
인스턴스 생성 (Create instance)
클래스에서 객체를 생성하려면 생성자를 사용하여 클래스 인스턴스를 선언합니다.
기본적으로 Kotlin은 클래스 헤더에 선언된 매개변수로 생성자를 자동으로 생성합니다.
예를 들어:
class Contact(val id: Int, var email: String)
fun main() {
val contact = Contact(1, "mary@gmail.com")
}
위의 예시에서:
- Contact는 클래스입니다.
- contact는 Contact 클래스의 인스턴스입니다.
- id와 email은 프로퍼티입니다.
- id와 email은 기본 생성자와 함께 사용되어 contact를 생성합니다.
Kotlin 클래스는 여러 생성자를 가질 수 있으며, 이 중에서 직접 정의한 생성자도 포함될 수 있습니다. 자세한 내용은 다양한 생성자를 선언하는 방법에 대해서는 "Constructors"를 참조하십시오.
프로퍼티 접근 (Access properties)
인스턴스의 프로퍼티에 접근하려면 인스턴스 이름 뒤에 점 .을 붙이고 프로퍼티 이름을 작성하면 됩니다:
class Contact(val id: Int, var email: String)
fun main() {
val contact = Contact(1, "mary@gmail.com")
// Prints the value of the property: email
println(contact.email)
// mary@gmail.com
// Updates the value of the property: email
contact.email = "jane@gmail.com"
// Prints the new value of the property: email
println(contact.email)
// jane@gmail.com
}
프로퍼티의 값을 문자열의 일부로 연결하려면 문자열 템플릿 ($ 기호)을 사용할 수 있습니다. 예를 들어:
println("Their email address is: ${contact.email}")
멤버 함수 (Member functions)
객체의 특성으로 프로퍼티를 선언하는 것 외에도 멤버 함수를 사용하여 객체의 동작을 정의할 수 있습니다.
Kotlin에서 멤버 함수는 반드시 클래스 본문 내에서 선언되어야 합니다. 인스턴스에서 멤버 함수를 호출하려면 인스턴스 이름 뒤에 점 .을 붙이고 함수 이름을 작성하면 됩니다. 예를 들어:
class Contact(val id: Int, var email: String) {
fun printId() {
println(id)
}
}
fun main() {
val contact = Contact(1, "mary@gmail.com")
// Calls member function printId()
contact.printId()
// 1
}
데이터 클래스 (Data classes)
Kotlin에는 데이터를 저장하는 데 특히 유용한 데이터 클래스가 있습니다. 데이터 클래스는 클래스와 동일한 기능을 가지지만 추가적인 멤버 함수가 자동으로 제공됩니다. 이러한 멤버 함수를 사용하면 인스턴스를 읽기 쉬운 출력으로 쉽게 변환하거나, 클래스의 인스턴스를 비교하거나, 인스턴스를 복사하는 등의 작업을 수행할 수 있습니다. 이러한 함수들은 자동으로 제공되기 때문에 각 클래스마다 동일한 보일러플레이트 코드를 작성할 필요가 없습니다.
데이터 클래스를 선언하려면 키워드 data를 사용하십시오:
data class User(val name: String, val id: Int)
가장 유용한 미리 정의된 데이터 클래스의 멤버 함수는 다음과 같습니다:
- toString(): 이 함수를 사용하면 인스턴스를 읽기 쉬운 문자열로 변환할 수 있습니다. 주로 디버깅 및 출력 목적으로 활용됩니다.
- equals(other: Any?): 두 인스턴스를 비교하여 내용이 같은지 확인하는 함수입니다. 자동으로 생성된 equals 함수는 모든 프로퍼티의 값을 비교합니다.
- hashCode(): 인스턴스의 해시 코드를 반환합니다. 해시 기반 컬렉션에서 유용하게 사용될 수 있습니다.
- copy(): 인스턴스를 복사하여 동일한 내용을 가진 새로운 인스턴스를 생성합니다. 이 함수를 사용하여 새로운 인스턴스를 만들면서 일부 프로퍼티를 변경할 수 있습니다.
- componentN(): 디스트럭처링 선언을 위한 함수로, 데이터 클래스의 각 프로퍼티에 대한 값을 반환합니다.
문자열로 출력 (Print as string)
클래스 인스턴스의 가독성 있는 문자열을 출력하려면 .toString() 함수를 명시적으로 호출하거나, .toString() 함수를 자동으로 호출해주는 출력 함수 (println() 및 print())를 사용할 수 있습니다:
// Automatically uses toString() function so that output is easy to read
println(user)
// User(name=Alex, id=1)
이 기능은 특히 디버깅이나 로그 생성 시에 유용합니다.
인스턴스 비교 (Compare instance)
인스턴스를 비교하려면 데이터 클래스의 경우 등호 연산자 == 를 사용하십시오:
val user = User("Alex", 1)
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)
// Compares user to second user
println("user == secondUser: ${user == secondUser}")
// user == secondUser: true
// Compares user to third user
println("user == thirdUser: ${user == thirdUser}")
// user == thirdUser: false
인스턴스 복사 (Copy instance)
데이터 클래스의 정확한 복사본을 생성하려면 해당 인스턴스에서 .copy() 함수를 호출하면 됩니다.
데이터 클래스 인스턴스의 복사본을 만들고 일부 프로퍼티를 변경하려면 인스턴스에서 .copy() 함수를 호출하고 프로퍼티에 대한 대체 값을 함수 매개변수로 추가하면 됩니다.
예를 들어:
val user = User("Alex", 1)
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)
// Creates an exact copy of user
println(user.copy())
// User(name=Alex, id=1)
// Creates a copy of user with name: "Max"
println(user.copy("Max"))
// User(name=Max, id=1)
// Creates a copy of user with id: 3
println(user.copy(id = 3))
// User(name=Alex, id=3)
인스턴스의 복사본을 생성하는 것은 원본 인스턴스를 수정하는 것보다 안전합니다. 왜냐하면 원본 인스턴스에 의존하는 코드는 복사본 및 해당 작업에 영향을 받지 않기 때문입니다.
더 많은 정보를 원한다면 데이터 클래스에 대한 내용을 참조하십시오.
이 투어의 마지막 장은 코틀린의 널 안전성에 대한 내용입니다.
연습 (Practice)
예제 1
다음은 두 개의 프로퍼티를 가진 Employee 데이터 클래스를 정의하는 예시입니다. 하나는 이름을 나타내고, 다른 하나는 급여를 나타냅니다. 급여 프로퍼티가 변경 가능한 형태(mutable)로 선언되어 있어야만 연말에 급여 인상을 받을 수 있습니다. 아래의 main 함수는 이 데이터 클래스를 어떻게 사용하는지를 보여줍니다.
fun main() {
val emp = Employee("Mary", 20)
println(emp)
emp.salary += 10
println(emp)
}
data class Employee(val name: String, var salary: Int)
fun main() {
val emp = Employee("Mary", 20)
println(emp)
emp.salary += 10
println(emp)
}
예제 2
당신의 코드를 테스트하려면 무작위 직원을 생성할 수 있는 생성기가 필요합니다. 클래스 내부에 잠재적인 이름 목록이 있는 클래스를 정의하고, 해당 클래스 헤더 내에서 최소 및 최대 급여로 구성되어야 합니다. 다시 한번, 메인 함수는 이 클래스를 어떻게 사용할 수 있는지를 보여줍니다.
힌트
리스트에는 .random()이라는 확장 함수가 있으며, 이 함수는 리스트 내에서 무작위 항목을 반환합니다.
Random.nextInt(from = ..., until = ...)를 사용하면 지정한 범위 내에서 무작위 정수 숫자를 얻을 수 있습니다.
import kotlin.random.Random
data class Employee(val name: String, var salary: Int)
// Write your code here
fun main() {
val empGen = RandomEmployeeGenerator(10, 30)
println(empGen.generateEmployee())
println(empGen.generateEmployee())
println(empGen.generateEmployee())
empGen.minSalary = 50
empGen.maxSalary = 100
println(empGen.generateEmployee())
}
import kotlin.random.Random
data class Employee(val name: String, var salary: Int)
class RandomEmployeeGenerator(var minSalary: Int, var maxSalary: Int) {
val names = listOf("John", "Mary", "Ann", "Paul", "Jack", "Elizabeth")
fun generateEmployee() =
Employee(names.random(),
Random.nextInt(from = minSalary, until = maxSalary))
}
fun main() {
val empGen = RandomEmployeeGenerator(10, 30)
println(empGen.generateEmployee())
println(empGen.generateEmployee())
println(empGen.generateEmployee())
empGen.minSalary = 50
empGen.maxSalary = 100
println(empGen.generateEmployee())
}
원문
'Kotlin' 카테고리의 다른 글
[Kotlin] Kotlin 공식 문서 번역 - 역호환성 (Backward compatibility) (0) | 2023.08.26 |
---|---|
[Kotlin] Kotlin 공식 문서 번역 - 데이터 클래스 (Data classes) (0) | 2023.08.26 |
[Kotlin] inline 사용법 (4) - crossinline 사용법 (1) | 2023.08.16 |
[Kotlin] inline 사용법 (3) - noinline 사용법 (0) | 2023.08.15 |
[Kotlin] inline 사용법 (2) - reified 사용법 (0) | 2023.08.15 |
댓글