본문 바로가기
코틀린/코틀린 공식문서

[코틀린 공식문서] Classes; 클래스

by 측면삼각근 2023. 8. 10.
728x90
반응형

들어가기 전에

해당 블로깅은 코틀린 공식문서의 Classes를 번역하며 학습한 내용입니다.

학습 중임에 따라 이해하는데 도움이 되는 부분들을 추가되고 의역된 부분이 있습니다. 혹시 잘못된 설명이 있다면 얼마든지 제보해 주세요.


 

클래스는 키워드를 사용하여 선언된다.

class Person { /*...*/ }

클래서 선언은 클래스 이름, 클래스 헤더(매개변수, 기본 생성자 및 기타 항목 지정) 및 중괄호로 둘러싸인 클래스 본문으로 구성된다.
헤더와 본문은 모두 선택사항이라, 클래스에 본문이 없다면, 중괄호를 생략할 수 있다.

class Empty

Construcotrs 생성자

코틀린 클래스는 기본 생성자와 하나 이상의 보조 생성자가 있을 수 있다.
기본 생성자는 클래스 헤더에 선언되며, 선택적 형식의 매개 변수 뒤에 온다.

class Person constructor(firstName: String) { /*...*/ }

기본 생성자에 주석 또는 가시성 지시자(public, private, protected)가 없는 경우 constructor 키워드를 생략할 수 있다.

class Person(firstName: String) { /*...*/ }

기본 생성자는 클래스 해더에서 클래스 인스턴스와 해당 속성을 초기화한다.

클래스 헤더에는 실행 가능한 코드가 포함될 수는 없다.
객체를 만드는 동안 코드 실행일 하기 위해서는, initializer block을 사용한다

인스턴스를 초기화하는 동안, 이니셜라이저 블록은 클래스 본문에 표시되는 순서와 동일한 순서로 실행된다.(위에서부터 아래로)

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}")
    }
}
/*
First property: hello
First initializer block that prints hello
Second property: 5
Second initializer block that prints 5
*/

기본 생성자 매개 변수는 이니셜라이저 블록에서 사용할 수 있다. 클래스 본문에 선언된 속성 이니셜라이저에서도 사용할 수 있다.

class Customer(name: String) {
    val customerKey = name.uppercase()
}

속성을 선언하고 기본 생성자에서 초기화하기 위한 구문이 있다.

class Person(val firstName: String, val lastName: String, var age: Int)

기본값 또한 포함될 수도 있다.

class Person(val firstName: String, val lastName: String, var isEmployed: Boolean = true)

클래스 속성을 선언할 때 후행쉼표도 가능하다.

class Person(
    val firstName: String,
    val lastName: String,
    var age: Int, // trailing comma
) { /*...*/ }

생성자에 어노테이션이나 가시성수정자가 있는 경우 constructor 키워드가 필요하다.

class Customer public @Inject constructor(name: String) { /*...*/ }

Secondary constructors 보조 생성자

클래스는 보조 생성자를 선언할 수 있으며, constructor라는 접두사가 붇는다.

class Person(val pets: MutableList<Pet> = mutableListOf())

class Pet {
    constructor(owner: Person) {
        owner.pets.add(this) //오너의 팻 리스트에 현재 pet을 추가
    }
}

클래스에 기본 생성자가 있는 경우 각 보조 생성자는 다른 보조 생성자를 통해 직-간접적으로 기본 생성자에게 위임해야 한다.
동일한 클래스의 다른 생성자에 대한 위임은 this키워드를 사용하여 수행된다.

class Person(val name: String) {
    val children: MutableList<Person> = mutableListOf()
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}

이니셜라이저 블록의 코드는 사실성 기본 생성자의 일부가 된다.

기본 생성자에 대한 위임은 보조 생성자의 첫번째 문에 액세스 하는 순간 발생하므로, 모든 이미셜라이저 블록 및 속성 이니셜라이저 코드는 보조 생성자의 본문보다 먼저 실행된다.

클래스에 기본 생성자가 없더라도 위임은 여전히 암시적으로 이루어 지며, 이니셜라이저 블록은 계속 실행된다.

class Constructors {
    init {
        println("Init block")
    }

    constructor(i: Int) {
        println("Constructor $i")
    }
}
/*
Init block
Constructor 1
*/

클래스의 생성자를 선언하지 않으면 인수없이 생성되는 기본 생성자가 있다.
생성자의 기본 표기는 Public이기 때문에 클래스에 공용 생성자가 없도록 하려면 private을 가진 기본 생성자를 선언해야 한다.

class DontCreateMe private constructor() { /*...*/ }

Create instances of classes 클래스의 인스턴스 만들기

클래스의 인스턴스를 만들려면 생성자를 일반 함수처럼 호출한다.

val invoice = Invoice()

val customer = Customer("Joe Smith")
코트린에는 new 키워드가 없다.

Class members

클래스에는 다음이 포함 될 수 있다.

  • Constructors and initializer blocks 생성자와 이니셜라이저 블럭
  • Functions 함수
  • Properties 프로퍼티(속성)
  • Nested and inner classes 중첩 및 내부 츨래스
  • Object declarations (객체 선언)

Inheritance 상속

클래스는 서로 파생 될 수 있으며, 상속 계층을 형성 할 수 있다.

Abstract classes 추상 클래스

추상 맴버는 클래스에 구현이 존재하지 않는다.

추상클래스에는 open어노테이션을 사용하지 않아도 괜찮다.

abstract class Polygon {
    abstract fun draw()
}

class Rectangle : Polygon() {
    override fun draw() {
        // draw the rectangle
    }
}

추상이 아닌 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()
}

Companion objects 컴패니언 개체

클래스 인스턴스 없이 호출할 수 있지만 클래스 내부에 액세스해야 하는 함수(예: 팩토리 메서드)를 작성해야 하는 경우 해당 클래스 내에서 객체 선언 맴버로 작성 할 수 있다.

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

val instance = MyClass.create()
반응형