본문 바로가기
공부/Programming Language

Kotlin 기본 문법 - 2

by Piva 2021. 4. 2.

  졸작을 마무리하느라 지난번 포스팅 이후로 손도 못 댔다... 지난 번에 이어서 코틀린 공식 문서(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, //여기 후행 쉼표 쓰임.
) { /* ... */}

 

  • 기본 생성자에서 정의되는 속성들은 varval 을 통해 정의될 수 있음.

 

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 (속성)

  • 속성을 정의할 때는 변수와 비슷하게 varval을 통해 가능.
  • 속성을 사용할 때는 이름으로 사용하면 됨.
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)

 

  • 컴파일러는 기본 생성자에 정의된 모든 속성에 대한 다음 멤버들을 자동적으로 오버라이딩함. (쩐다!)
  1. equals() / hashCode()
  2. toString()
  3. componentN() : 분리 선언을 할 때 필요한 함수.
    * 분리 선언 : 객체의 값을 여러 변수로 분리해서 사용하는 것.
  4. 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