웹사이트 검색

Kotlin 클래스 - Kotlin 생성자


이 튜토리얼에서는 Kotlin의 객체 지향 프로그래밍 개념에 대해 설명합니다. Kotlin 클래스에 대해 자세히 설명하겠습니다. 또한 kotlin 생성자, 액세스 수정자 및 추상 클래스도 살펴보겠습니다.

코틀린 클래스

class FirstClass {
}

클래스의 인스턴스는 다음과 같은 방식으로 인스턴스화됩니다.

val firstClass =  FirstClass()
var new = FirstClass() //here new is the name of the var.

Java와 달리 new는 Kotlin의 키워드가 아닙니다. 기본적으로 클래스는 Kotlin에서 최종 클래스입니다. 따라서 Java에서 위의 정의에 해당하는 것은 다음과 같습니다.

public final class FirstClass {
}

따라서 Kotlin의 기본 클래스는 상속할 수 없습니다. 클래스를 non-final로 만들려면 open 키워드를 추가해야 합니다.

open class Me{
}

open 주석을 사용하면 다른 사용자가 이 클래스를 상속할 수 있습니다.

Kotlin 클래스 예제

몇 가지 함수와 속성이 있는 클래스를 만들어 봅시다. 해당 클래스의 기능과 속성에 액세스하는 방법을 살펴보겠습니다. 또한 멤버 속성을 설정하는 방법을 살펴보겠습니다.

class User {

    var loggedIn: Boolean = false
    val cantChangeValue = "Hi"
    
    fun logOn() {
        loggedIn = true
    }
    
    fun logOff() {
        loggedIn = false
    }
}

fun main(args: Array<String>) {

    val user = User()
    println(user.loggedIn) //false
    user.logOn()
    println(user.loggedIn) //true
    user.logOff()
    println(user.loggedIn) //false
    user.cantChangeValue = "Hey" //won't compile. Can't modify a final variable.

}

함수 mainTest.kt 클래스에 속합니다. 멤버 및 함수에 액세스하려면 점 연산자를 사용해야 합니다. 점 연산자를 사용하여 val 속성을 다시 설정할 수 없습니다.

코틀린 초기화

Kotlin 초기화 블록은 아래와 같이 정의됩니다.

class User {
    
    init{
        print("Class instance is initialised.")
    }

    var loggedIn: Boolean = false
    val cantChangeValue = "Hi"

    fun logOn() {
        loggedIn = true
    }

    fun logOff() {
        loggedIn = false
    }
}

init 블록 내부의 코드는 클래스가 인스턴스화될 때 가장 먼저 실행됩니다. init 블록은 클래스가 인스턴스화될 때마다 실행되며 다음에 보게 될 모든 종류의 생성자와 함께 실행됩니다. 클래스에 여러 이니셜라이저 블록을 작성할 수 있습니다. 아래와 같이 순차적으로 실행됩니다.

class MultiInit(name: String) {

    init {
        println("First initializer block that prints ${name}")
    }

    init {
        println("Second initializer block that prints ${name.length}")
    }
}

fun main(args: Array<String>) {
    var multiInit = MultiInit("Kotlin")
}

//Following is printed in the log console.
//First initializer block that prints Kotlin
//Second initializer block that prints 6

Kotlin 클래스는 아래와 같이 also 함수를 사용하여 선언 자체의 속성 인쇄를 허용합니다.

class MultiInit(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}")
    }
}

fun main(args: Array<String>) {

    var multiInit = MultiInit("Kotlin")
}

//Following gets printed.
//First property: Kotlin
//First initializer block that prints Kotlin
//Second property: 6
//Second initializer block that prints 6

코틀린 생성자

Kotlin 생성자는 속성을 초기화하는 데 사용되는 특수 멤버 함수입니다. Kotlin의 생성자는 Java와 다르게 작성되고 구성됩니다. 기본적으로 클래스에는 아래와 같이 빈 생성자가 있습니다.

class Student {
    var name: String
    val age : Int

    init {
        name = "Anupam"
        age = 24
    }

    init {
        name = "Anupam Chugh"
        //age = 26
    }
}

fun main(args: Array<String>) {
    
    val student = Student()
    println("${student.name} age is ${student.age}")
    student.name = "Your"
    //student.age = 26 //won't compile. age is val
    println("${student.name} age is ${student.age}")

}

//Following is printed on the console:
//Anupam Chugh age is 24
//Your age is 24

기본 생성자

Kotlin의 기본 생성자는 아래와 같이 클래스 헤더 자체에 정의됩니다.

class User(var name: String, var isAdmin: Boolean) {

    init {
        name = name + " @ JournalDev.com"
        println("Author Name is $name. Is Admin? $isAdmin")
    }
}

기본 생성자 정의는 클래스 헤더 내부에 있습니다. 생성자 자체에서 속성 유형(val/var)을 정의했습니다. 참고: var로 지정되지 않은 경우 기본적으로 생성자 인수는 val입니다.

class User(name: String, isAdmin: Boolean)

위의 코드에서 name과 isAdmin은 모두 재할당할 수 없습니다. 또는 아래와 같이 클래스의 멤버 속성에 생성자 인수를 할당할 수도 있습니다.

class User(name: String, val isAdmin: Boolean) {

    var username  = name
    val _isAdmin = isAdmin

    init {
        username= username + " @ JournalDev.com"
        println("Author Name is $name. Is Admin? $_isAdmin")
    }
}

fun main(args: Array<String>) {

    var user = User("Anupam",false)
    user.isAdmin = true //won't compile since isAdmin is val
    user._isAdmin = true //won't compile. Same reason.
    user = User("Pankaj",true)
}

//Following is printed in the log console.
//Author Name is Anupam. Is Admin? false
//Author Name is Pankaj. Is Admin? true

Kotlin 생성자 기본값

Kotlin을 사용하면 아래와 같이 생성자 자체에서 기본값을 지정할 수 있습니다.

class User(name: String, var website: String = "JournalDev") {

    init {
        println("Author $name writes at $website")
    }

    init {
        website = website + ".com"
        println("Author $name writes at $website")
    }
}

fun main(args: Array<String>) {

    var user = User("Anupam","JournalDev")
    user = User("Pankaj","JournalDev")
}

//Following is printed on the console:
//Author Anupam writes at JournalDev
//Author Anupam writes at JournalDev.com
//Author Pankaj writes at JournalDev
//Author Pankaj writes at JournalDev.com

보조 생성자

Secondary Constructor는 constructor 키워드를 접두사로 사용하여 클래스 본문 내부에 작성됩니다. 다음 예제는 동일한 내용을 보여줍니다.

class Student {
    var name: String
    val age : Int

    constructor(name: String, age: Int)
    {
        this.name = name
        this.age = age
    }

    fun printDetails()
    {
        println("Name is $name and Age is $age")
    }

}

fun main(args: Array<String>) {

    var student = Student("Anupam", 24)
    student.printDetails()
}

//Following is printed in the console.
//Name is Anupam and Age is 24

다른 방법으로 클래스를 초기화해야 하는 경우 보조 생성자의 가장 일반적인 용도는 하위 클래스에서 제공됩니다. 클래스에 기본 생성자가 포함된 경우 보조 생성자는 선언에서 이를 참조해야 합니다. 선언은 this 키워드를 사용하여 수행됩니다.

class Student(var name: String, val age: Int) {

    var skill: String

    init {
        skill = "NA"
    }

    constructor(name: String, age: Int, skill: String) : this(name, age) {
        this.skill = skill
    }

    fun printDetails() {
        if (skill.equals("NA"))
            println("Name is $name and Age is $age")
        else
            println("Name is $name and Age is $age Skill is $skill")
    }
}

//Following is printed in the log console:
//Name is Anupam and Age is 24
//Name is Anupam and Age is 24 Skill is Kotlin

init 블록은 멤버 속성 skill을 초기화하는 데 사용됩니다. 보조 생성자는 : this를 사용하여 기본 생성자에게 위임합니다.

사용자 지정 Getter 및 Setter

지금까지 클래스의 인스턴스에서 점 연산자를 사용하여 클래스의 속성에 액세스하고 수정했습니다. setget 구문을 사용하여 액세스를 사용자 정의하는 방법을 살펴보겠습니다.

class Name{
    var post: String = "default"
    set(value) {if(!post.isNotEmpty()) {
        throw IllegalArgumentException(" Enter a valid name")
    }
                field = value
                print(value)
    }

}

fun main(args: Array<String>) {

    var name = Name()
    name.post = "Kotlin Classes"
    name.post = ""
    name.post = "Kotlin Data Classes Our Next Tutorial"


}

다음은 로그 콘솔에 인쇄됩니다.

Kotlin Classes

Exception in thread "main" java.lang.IllegalArgumentException:  Enter a valid name
	at Name.setPost(Test.kt:16)
	at TestKt.main(Test.kt:78)

setter의 field 변수는 이전 값을 저장합니다. 게터를 추가합시다.

class Name{
    var post: String = "default"
    set(value) {if(!post.isNotEmpty()) {
        throw IllegalArgumentException(" Enter a valid name")
    }
                field = value
    }
    get() {
        return field.capitalize()
    }

}

fun main(args: Array<String>) {

    var name = Name()
    name.post = "kotlin classes"
    println(name.post)
    name.post = "kotlin data Classes our next Tutorial"
    println(name.post)

}

//Following is printed:
//Kotlin classes
//Kotlin data Classes our next Tutorial

capitalize()는 문자열의 첫 글자를 대문자로 만듭니다. 참고: 속성이 val인 경우 set 메서드는 컴파일되지 않습니다.

Kotlin 가시성 수정자

  • 공용: 이 수정자가 있는 모든 클래스, 함수, 속성, 인터페이스 또는 개체를 볼 수 있으며 어디에서나 액세스할 수 있습니다.
  • Private: 이 수정자로 정의된 클래스/함수는 동일한 파일 내에서만 액세스할 수 있습니다. 이 한정자가 있는 클래스/함수의 멤버/속성은 해당 블록 내에서만 액세스할 수 있습니다.
  • Protected : 이 수정자는 하위 클래스 내에서 가시성 및 액세스를 허용한다는 점을 제외하면 private과 동일합니다.
  • 내부: 이 수정자가 있는 클래스/인터페이스/함수는 동일한 모듈 내에서만 액세스할 수 있습니다.

가시성 수정자는 생성자에도 적용할 수 있습니다. 기본 생성자에 수정자를 할당하려면 클래스 헤더의 생성자 옆에 constructor 키워드를 지정해야 합니다.

class Student private constructor (var name: String, val age: Int) {

    var skill: String

    init {
        skill = "NA"
    }

    constructor(name: String, age: Int, skill: String) : this(name, age) {
        this.skill = skill
    }

    fun printDetails() {
        if (skill.equals("NA"))
            println("Name is $name and Age is $age")
        else
            println("Name is $name and Age is $age Skill is $skill")
    }
}

fun main(args: Array<String>) {

    var student = Student("Anupam",24,"Kotlin")
    student.printDetails()
}

//prints
//Name is Anupam and Age is 24 Skill is Kotlin

비공개 생성자는 클래스 외부에서 호출할 수 없습니다. 위의 코드에서는 보조 생성자만 사용하여 다른 함수에서 클래스를 인스턴스화할 수 있습니다.

Kotlin 추상 클래스

Java와 마찬가지로 abstract 키워드는 Kotlin에서 추상 클래스를 선언하는 데 사용됩니다. Abstract 클래스는 인스턴스화할 수 없습니다. 그러나 하위 클래스에 의해 상속될 수 있습니다. 기본적으로 추상 클래스의 멤버는 달리 명시되지 않는 한 비추상 클래스입니다.

abstract class Person(name: String) {

    init {
        println("Abstract Class. init block. Person name is $name")
    }

    abstract fun displayAge()
}

class Teacher(name: String): Person(name) {

    var age : Int

    init {
        age = 24
    }

    override fun displayAge() {
        println("Non-abstract class displayAge function overridden. Age is $age")
    }
}

fun main(args: Array<String>) {

    val person = Teacher("Anupam")
    person.displayAge()

}

//Following is printed in the console.
//Abstract Class. init block. Person name is Anupam
//Non-abstract class. Age is 24

참고: 추상 클래스는 기본적으로 open입니다. 따라서 서브클래싱을 허용하기 위해 open 한정자를 추가할 필요가 없습니다. override 키워드는 하위 클래스의 메서드를 재정의하는 데 사용됩니다. 이 튜토리얼에서는 kotlin 클래스의 기본 사항을 다뤘습니다. Data Classes, Sealed Classes, Inheritance 등과 같은 훨씬 더 많은 것들이 있습니다. 우리는 다가오는 튜토리얼에서 그것들을 다룰 것입니다. 참조 : Kotlin 문서