•
class 키워드를 사용하여 선언
class Person { /*...*/ }
Kotlin
복사
•
클래스 선언은 클래스 이름, 클래스 헤더 그리고 중괄호로 둘러싸인 클래스 본체로 구성된다.
•
클래스 헤더와 본체는 선택사항으로 본체가 없는 경우 중괄호를 생략할 수 있다.
class Empty
Kotlin
복사
•
클래스 헤더의 구성
◦
타입 매개변수(Type Parameters) : 제네릭 클래스를 만들 때 사용
◦
주 생성자 (Primary Constructor) : 클래스의 주요 생성자를 정의하고 생성자의 매개변수는 클래스의 속성을 초기화하는데 사용
◦
상위 클래스와 인터페이스 (Superclass and Interfaces) : 클래스가 상속하거나 구현할 상위 클래스와 인터페이스를 지정할 수 있다.
// 상위 클래스
open class Animal(val species: String) {
open fun makeSound() {
println("Some generic animal sound")
}
}
// 인터페이스
interface Pet {
fun play()
}
// 클래스 선언
class Dog<T>(
species: String,
val name: String,
var age: Int
) : Animal(species), Pet {
// 타입 매개변수를 사용하는 속성
var favoriteToy: T? = null
// 메소드 구현
override fun makeSound() {
println("Bark!")
}
// 인터페이스 메소드 구현
override fun play() {
println("$name is playing")
}
}
Kotlin
복사
Constructor
•
Kotlin 클래스에는 기본 생성자와 하나 이상의 보조 생성자가 있다.
•
기본 생성자는 constructor 키워드를 통해 클래스 헤더에 선언되며 주석이나 가시성 수정자가 없으면 생략할 수 있다.
•
주석이나 가시성 수정자가 존재한다면 constructor 키워드 앞에 위치한다.
//constructor 키워드를 생략하지 않은 경우
class Person constructor(firstName: String) { /*...*/ }
//constructor 키워드를 생략한 경우
class Person(firstName: String) { /*...*/ }
//주석이나 가시성 수정자가 존재하는 경우
class Customer public @Inject constructor(name: String) { /*...*/ }
Kotlin
복사
•
기본 생성자는 클래스 헤더에서 클래스 인스턴스와 해당 속성을 초기화하며 실행 가능한 코드가 포함될 수 없다.
•
객체 생성 중에 코드를 실행하려면 클래스 본문 내부에 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.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
Kotlin
복사
•
Kotlin은 속성을 선언하고 기본 생성자에서 이를 초기화하기 위한 간결한 구문을 제공한다.
•
기본 생성자에서 클래스 속성을 선언할 때 기본값을 포함할 수 있다.
•
기본 생성자에서 클래스 속성을 선언할 때 후행 쉼표를 사용할 수 있다.
class Person(
val firstName: String,
val lastName: String,
var isEmployed: Boolean = true,
)
Kotlin
복사
Secondary constructors
•
클래스는 constructor 접두사로 2차 생성자를 선언할 수 있다.
class Person(val pets: MutableList<Pet> = mutableListOf())
class Pet {
constructor(owner: Person) {
owner.pets.add(this) // adds this pet to the list of its owner's pets
}
}
Kotlin
복사
•
클래스에 기본 생성자가 있는 경우 각 보조 생성자는 기본 생성자에게 직접 또는 다른 보조 생성자를 통해 간접적으로 위임해야 한다.
•
같은 클래스의 다른 생성자에게 위임하는 것은 this 키워드를 사용하여 수행한다.
class Person(val name: String) {
val children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
Kotlin
복사
•
초기화 블록의 코드는 기본 생성자의 일부가 된다.
•
기본 생성자에 대한 위임은 보조 생성자의 첫 번째 문장에 엑세스하는 순간에 발생하므로 모든 초기화 블록과 프로퍼티 초기화자의 코드는 보조 생성자의 본문보다 먼저 실행된다.
•
클래스에 기본 생성자가 없더라도 위임은 여전히 암묵적으로 발생하고 초기화 블록은 계속 실행된다.
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor $i")
}
}
Kotlin
복사
•
추상이 아닌 클래스가 생성자(1차 또는 2차)를 선언하지 않으면 인수가 없는 1차 생성자를 갖고 기본적으로 생성자의 가시성은 public이 된다.
•
만약 public이 아닌 생성자를 만들고 싶다면 명시적으로 정의해야한다.
class DontCreateMe private constructor() { /*...*/ }
Kotlin
복사
•
기본 생성자 매개변수 모두가 기본값이 있는 경우 컴파일러는 기본값을 사용하는 추가 매개변수가 없는 생성자를 생성한다.
•
이것은 매개변수가 없는 생성자를 사용하여 클래스를 생성하는 Jackson 또는 JPA 와 함께 Kotlin을 사용하기 쉽게 만들어준다.
class Customer(val customerName: String = "")
Kotlin
복사
클래스 인스턴스 생성
•
클래스 인스턴스를 만들려면 생성자를 일반 함수인 것처럼 호출한다.
•
생성된 인스턴스를 변수에 할당할 수 있다.
•
Kotlin에는 new 키워드가 없다.
val invoice = Invoice()
val customer = Customer("Joe Smith")
Kotlin
복사
클래스 구성
•
생성자 및 초기화 블록
•
함수
•
프로퍼티
•
중첩된 클래스와 내부 클래스
•
객체 선언
추상 클래스
•
abstract 클래스는 일부 또는 모든 멤버와 함께 선언될 수 있다.
•
추상 멤버는 클래스에 구현이 없다.
•
open 키워드가 붙은 추상 클래스나 함수에 주석을 달 필요가 없다.
abstract class Polygon {
abstract fun draw()
}
class Rectangle : Polygon() {
override fun draw() {
// draw the rectangle
}
}
Kotlin
복사
•
추상적이지 않은 open 멤버를 추상화된 멤버로 재정의할 수 있다.
open class Polygon {
open fun draw() {
// some default polygon drawing method
}
}
abstract class WildShape : Polygon() {
// Classes that inherit WildShape need to provide their own
// draw method instead of using the default on Polygon
abstract override fun draw()
}
Kotlin
복사
동반 객체
•
클래스 인스턴스가 없어도 호출할 수 있지만 클래스 내부에 엑세스해야 하는 함수를 작성해야 하는 경우 해당 클래스 내부에 객체 선언의 멤버로 작성할 수 있다.
•
더 구체적으로 클래스 내부에 동반 객체를 선언하면 클래스 이름만을 사용하여 해당 멤버에 엑세스할 수 있다.
•
Java의 static 멤버와 유사하며 동반 객체에 정의된 함수나 변수는 클래스의 private 멤버에도 접근할 수 있다.
class MyClass private constructor(val name: String) {
companion object {
fun create(name: String): MyClass {
return MyClass(name)
}
}
fun printName() {
println("My name is $name")
}
}
fun main() {
// 동반 객체의 create 메서드를 사용하여 MyClass의 인스턴스를 생성
val myObject = MyClass.create("Kotlin")
// 인스턴스의 메서드 호출
myObject.printName()
}
Kotlin
복사