졸작을 마무리하느라 지난번 포스팅 이후로 손도 못 댔다... 지난 번에 이어서 코틀린 공식 문서(kotlinlang.org/docs/home.html)의 내용을 해석한 내용이 주류이다. 역시나 공부하면서 끄적인 걸 가져온 탓에 설명이 간결하고 짧음. (추가 예정)
1. Class
- 코틀린에서 클래스는 class로 정의함.
- 클래스의 정의에는 해당 클래스의 이름, (타입 패러미터와 주요 생성자 등을 정의하는) 헤더, body 등이 포함됨.
- 위의 항목들은 중괄호 안에 들어가나 헤더 및 body는 모두 필수적인 것들이 아니므로, body가 없다면 그냥 중괄호 자체를 생략해도 무방.
class Color { /* ... */ }
//클래스 선언에 아무런 body 가 없을 경우 중괄호 생략
class Empty
2. Constructor (생성자)
- 코틀린의 클래스는 기본 생성자(Primary Constructor) 와 한 개 혹은 그 이상의 부 생성자(Secondary Constructor) 를 가질 수 있다.
- 기본 생성자는 클래스의 헤더 부분에 있다. (클래스 이름 다음에 위치함.)
class Person constructor(firstName: String) { /* ... */ }
- 만약 생성자가 아무런 어노테이션 혹은 접근제어자(Visibility Modifiers)를 갖고 있지 않다면, constructor 키워드는 생략될 수 있음.
//Constructor를 생략한 모습
class Person(firstName: String) { /* ... */ }
※ 반대로 말하자면, 어노테이션이나 접근 제어자가 존재할 경우 constructor 는 반드시 사용되어야 하며, 접근 제어자는 constructor의 앞쪽에 위치하게 됨.
- 기본 생성자는 아무런 코드를 가질 수 없음. 단, 초기화에 대한 코드는 초기화 블록에 들어갈 수 있으며, 이 초기화 블록은 init 을 통해 정의됨.
- 클래스 인스턴스의 초기화 과정에서, 초기화 블록 내의 코드는 클래스 body에 나열된 순서대로 실행됨. (밑의 예시 참고)
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First Initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
/*
Output :
First property: hello
First initializer block that prints hello
Second property: 5
Second initializer block that prints 5
*/
- 기본 생성자 내의 패러미터는 초기화 블록에서 사용될 수 있음.
- 또한, 코틀린에는 속성들을 정의하고 기본 생성자를 통해 이들을 초기화하는 일련의 과정을 간단한 문법으로 처리하는 것이 가능.
class Person(val firstName: String, val lastName: String, var age: Int) { /* ... */}
- 클래스 속성 정의 시 Trailing commas(후행 쉼표)를 사용하는 것이 가능.
class Person(
val firstName: String,
val lastName: String,
var age: Int, //여기 후행 쉼표 쓰임.
) { /* ... */}
- 기본 생성자에서 정의되는 속성들은 var 나 val 을 통해 정의될 수 있음.
3. Secondary constructors (부 생성자)
- 클래스는 부 생성자를 정의할 수 있음.
- 만약 클래스가 기본 생성자를 가지고 있다면, 각 부 생성자는 기본 생성자의 역할을 직/간접적으로 위임(Delegate)해야 한다. 같은 클래스 내의 다른 생성자로의 위임은 this 를 통해 이루어진다.
class Person(val name: String) {
var children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
- 기본 생성자로의 위임은 부 생성자의 첫 번째 문장과 함께 이루어지며, 그러므로 모든 초기화 블록 및 속성 초기화 내의 코드는 부 생성자의 body 이전에 실행되어야 함.
※ 클래스가 기본 생성자를 가지고 있지 않아도, 이러한 위임은 암시적으로 이루어지며, 초기화 블록 또한 여전히 실행된다.
4. 클래스의 인스턴스 생성
- 클래스의 인스턴스를 생성하기 위해서는, 일반적인 함수를 호출하듯 생성자를 호출하면 된다.
val invoice = Invoice()
val customer = Customer("Happiva")
※ 코틀린에는 new가 없음!
5. Properties (속성)
- 속성을 정의할 때는 변수와 비슷하게 var나 val을 통해 가능.
- 속성을 사용할 때는 이름으로 사용하면 됨.
fun copyAddress(address: Address): Address {
val result = Address() //코틀린에는 new 없음!
result.name = address.name
result.street = address.street
//...
}
6. Getter & Setter (획득자와 설정자)
- 속성의 정의에 필요한 전체적인 문법은 아래와 같다.
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
- 초기화(초기자)와 획득자, 설정자는 필수가 아님. 또한, 초기화에서 추측할 수 있다면 속성의 타입 또한 필수로 기입하지 않아도 됨.
- 속성에 대해 커스텀 접근자를 정의하는 것도 가능. 커스텀 접근자를 정의할 경우, 어느 속성에 접근할 때마다 해당 접근자를 호출하게 될 것.
val isEmpty: Boolean
get() = this.size == 0
7. Backing Field (뭔소린지 모르겠음)
- 코틀린의 클래스는 field를 가질 수 없음.
- Backing Field 는 획득자/설정자에 기본적으로 생성되는 속성이며, field를 통해 접근할 수 있음.
- 속성의 접근자에서만 사용이 가능하며, 접근자 중 1개라도 기본 구현(Implement)를 사용하는 경우, 커스텀 접근자에서 field 식별자를 참조하는 경우 생성됨.
8. Data class
- 오직 데이터를 담기 위해 사용되는 클래스.
- data를 사용하여 표기됨.
data class User(val name: String, val age: Int)
- 컴파일러는 기본 생성자에 정의된 모든 속성에 대한 다음 멤버들을 자동적으로 오버라이딩함. (쩐다!)
- equals() / hashCode()
- toString()
- componentN() : 분리 선언을 할 때 필요한 함수.
* 분리 선언 : 객체의 값을 여러 변수로 분리해서 사용하는 것. - copy() : 객체를 복사할 때 일부 값을 변경하고 싶은 경우 사용.
'공부 > Programming Language' 카테고리의 다른 글
C++ 3일차 (1) | 2021.05.03 |
---|---|
C++ 2일차 (0) | 2021.04.30 |
C++ 1일차 (0) | 2021.04.28 |
C++ 공부 (0) | 2021.04.28 |
Kotlin 기본 문법 - 1 (0) | 2021.03.23 |