[Kotlin] 코틀린 기본 문법(클래스 1)

5 minute read


클래스는 내용이 많기 때문에 포스팅 2개로 나뉘어 작성됩니다.


클래스 1

클래스란 쉽게 그룹화할 수 있는 함수와 변수들을 한 군데에 모아 놓고 사용하기 쉽게 이름을 붙여놓은 것이라고 생각할 수 있습니다.


1. 클래스의 기본 구조


클래스의 기본 구조

class 클래스명{
    // 클래스 스코프 (class scope)
    var 변수
    fun 함수(){
        // 함수 코드
    }
}



2. 클래스 코드 작성하기


프라이머리 생성자

클래스를 사용한다는 것은 곧 클래스라는 이름으로 묶여있는 코드를 실행하는 것이기 때문에 함수 형태로 제공되는 생성자를 호출해야지만 클래스가 실행됩니다.

프라이머리primary 생성자는 마치 클래스의 헤더처럼 사용할 수 있으며 constructor 키워드를 사용해서 정의하는데 조건에 따라 생략할 수 있습니다.

class Person constructor(value: String)


생성자에 접근 제한자나 다른 옵션이 없다면 contructor 키워드를 생략할 수 있습니다.

class Person(value: String){}


클래스의 생성자가 호출되면 클래스 스코프 내의 init 블록의 코드가 실행되고, init 블록에서는 생성자를 통해 넘어온 파라미터에 접근할 수 있습니다.

class Person(value: String){
    init{
        Log.d("class","생성자로부터 전달받은 값은 ${value}입니다")
    }
}

이를 초기화 작업이라 하는데, 만약 init 초기화 작업이 필요하지 않다면 init 블록을 작성하지 않아도 됩니다.

다만, 그럴 경우 파라미터로 전달된 값을 사용하기 위해서는 파라미터 앞에 변수 키워드인 val을 붙여주어야 합니다. 그러면 클래스 스코프 전체에서 해당 파라미터를 사용할 수 있습니다.

class Person(val value: String){
    fun process(){
        print(value)
    }
}


생성자 파라미터 앞에는 var도 사용할 수 있지만, 읽기 전용인 val을 사용하는 것이 권장됩니다.


세컨더리 생성자

세컨더리secondary 생성자는 constructor 키워드를 마치 함수처럼 클래스 스코프 안에 직접 작성할 수 있습니다. 그리고 다음과 같이 init 블록을 작성하지 않고 constructor 다음에 괄호를 붙여서 코드를 작성합니다.

class Person{
    constructor(value: String){
        Log.d("class", "생성자로부터 전달받은 값은 ${value}입니다")
    }
}

세컨더리 생성자는 파라미터의 개수, 또는 파라미터의 타입이 다르다면 여러 개를 중복해서 만들 수 있습니다.

class Person{
    constructor(value: String){
        Log.d("class", "생성자로부터 전달받은 값은 ${value}입니다")
    }
    constructor(value: Int){
        Log.d("class", "생성자로부터 전달받은 값은 ${value}입니다")
    }
    constructor(value1: Int, value2: String){
        Log.d("class", "생성자로부터 전달받은 값은 ${value1}, &{value2}입니다")
    }
}


Default 생성자

생성자를 작성하지 않을 경우 파라미터가 없는 프라이머리 생성자가 하나 있는 것과 동일합니다.

class Student{ // 생성자를 작성하지 않아도 기본 생성자가 동작합니다. 
    init{
        // 기본 생성자가 없더라도 초기화가 필요하면 여기에 코드를 작성합니다. 
    }
}



3. 클래스의 사용


클래스 (생성자) 호출의 기본 구조

클래스명()

‘클래스 생성자 호출 -> init 블록 실행 -> 세컨더리 생성자 실행’ 순으로 동작합니다.


클래스의 생성자를 호출한 후 생성되는 것을 인스턴스instance라고 하고 변수에 담아둘 수 있습니다.

var kotlin = Kotlin()
var one = Person("value")
var two = Person(1004)

서로 다른 생성자의 호출로 생성된 인스턴스는 모두 다른 인스턴스입니다.


프로퍼티와 메서드

  • 프로퍼티(Property): 클래스 안에 정의된 변수로 멤버 변수라고도 한다. 단, 클래스 안이더라도 함수 안에 정의된 변수는 그냥 변수(또는 지역 변수)라고 한다.
  • 메서드(Method): 클래스 안에 정의된 함수로 멤버 함수라고도 한다.

인스턴스가 담긴 변수명 다음에 도트 연산자(.)를 붙여서 프로퍼티와 메서드를 참조할 수 있습니다.

class Pig{
    var name: String = "Pinky"
    fun printName(){
        Log.d("class", "Pig의 이름은 ${name}입니다. ")
    }
}

var pig = Pig()

pig.name = "Pooh"
pig.printName()



4. 오브젝트


오브젝트object를 사용하면 클래스를 인스턴스화 하지 않아도 블록 안의 프로퍼티와 메서드를 호출해서 사용할 수 있습니다. (java의 static과 같은 역할)

  • 오브젝트 선언 기본 구조
object Pig{
    var name: String = "Pinky"
    fun printName(){
        Log.d("class", "Pig의 이름은 ${name}입니다. ")
    }
}

Pig.name = "Mikey"
Pig.printName()

출력

Pig 이름은 Mikey입니다. 


컴패니언 오브젝트(Companion object)

일반 클래스에 object 기능을 추가하기 위해 사용합니다.

Pig 코드를 다음과 같이 companion object 블록으로 감싸주면 생성 과정 없이 오브젝트처럼 사용할 수 있습니다.

class Pig{
    companion object{
        var name: String = "Pinky"
        fun printName(){
            Log.d("class", "Pig의 이름은 ${name}입니다. ")
        }
    }
    fun walk(){
        Log.d("class", "Pig가 걸어갑니다.")
    }
}

위의 코드에서 name 프로퍼티와 printName 메서드는 인스턴스 생성 없이 참조할 수 있고, walk 메서드는 인스턴스 생성 후 참조가 가능합니다.

// companion object 안의 코드
Pig.name = "Linda"
Pig.printName()
// companion object 밖의 코드
val cutePig = Pig()
cutePig.walk()



5. 데이터 클래스


데이터 클래스는 간단한 값들의 저장을 위해 쓰이는 클래스입니다.

  • 데이터 클래스 선언 기본 구조

    data class 클래스명 (val 파라미터1: 타입, var 파라미터2: 타입)
    

    데이터 클래스를 정의할 때는 일반 클래스와 달리 생성자 파라미터 앞의 var(또는 val) 키워드를 생략할 수 없습니다.

    주로 코드 블록(클래스 스코프)을 사용하지 않고 간단하게 작성합니다.


👍 예시

data class UserData(val name: String, var age: Int)

var userData = UserData("Michael", 21)

userData.name = "Sindy" (X)
iserData.age = 18 (O)


toString() 메서드와 copy() 메서드

일반 클래스에서 toString() 메서드를 호출하면 인스턴스의 주소 값을 반환하지만, 데이터 클래스는 값을 반환하기 때문에 실제 값을 모니터링할 때 좋습니다.

Log.d("DataClass", "DataUser는 ${dataUser.toString()}")

출력

DataUser DataUser(name=Michael, age=21)


copy() 메서드는 간단하게 값을 복사해줍니다.

var newData = dataUser.copy()


일반 클래스처럼 사용하기

데이터 클래스도 일반 클래스와 마찬가지로 init 블록과 메서드의 사용 등이 가능합니다.

data class UserData(var name: String, var age: Int){
    init{
        Log.d("UserData", "initialized")
    }
    fun process(){
        // 실행 코드
    }
}

데이터 클래스는 주로 네트워크를 통해 데이터를 주고받거나, 혹은 로컬 앱의 데이터베이스에서 데이터를 다루기 위한 용도로 사용합니다.



정리


  • 클래스는 class 키워드를 사용하여 정의하고, 클래스 내부에는 변수(프로퍼티)와 함수(메서드)를 선언 및 정의할 수 있습니다.
  • 클래스 인스턴스의 생성은 생성자의 호출로 이루어지며, 생성자에는 프라이머리 생성자, 세컨더리 생성자, default 생성자가 있습니다.
    • 프라이머리 생성자는 constructor 키워드를 사용하여 정의하며 괄호 안에 파라미터를 정의합니다. 프라이머리 생성자의 경우 접근 제한자나 다른 옵션이 없다면 constructor 키워드를 생략할 수 있습니다.
      • 생성자가 호출되면 init 블록이 호출되어 초기화를 진행합니다.
      • 초기화 작업이 필요없는 경우 init 블록을 작성하지 않아도 되는데, 그럴 경우 파라미터로 전달된 값을 사용하기 위해서는 val 키워드를 붙여줘야 클래스 스코프 전체에서 파라미터를 사용할 수 있습니다.
    • 세컨더리 생성자는 클래스 스코프 내에 constructor 함수를 만들어서 사용합니다. 파라미터의 개수 또는 타입이 다르다면 여러 개의 세컨더리 생성자를 만들 수 있습니다.
    • Default 생성자는 프라이머리 생성자 또는 세컨더리 생성자를 작성하지 않은 경우로, 기본 생성자가 동작합니다. 이런 경우에도 init 블록을 작성하여 초기화를 진행할 수 있습니다.
  • 클래스는 클래스명 뒤에 ( )를 붙여서 호출하며, 괄호 안에 생성자 파라미터들을 전달합니다. 클래스 호출 시 인스턴스가 생성되는 데, 인스턴스를 변수에 저장하여 사용할 수 있습니다.
    • 클래스 내에 프로퍼티와 메서드는 도트 연산자(.)를 사용하여 참조할 수 있습니다.
  • 오브젝트를 사용하면 클래스를 인스턴스와 하지 않아도 블록 안의 프로퍼티와 메서드를 호출해서 사용할 수 있습니다. 이는 자바에서 static class와 같은 역할을 한다고 할 수 있습니다.
    • 오브젝트는 object 키워드를 이용하여 정의합니다.
    • 컴패니언 오브젝트는 일반 클래스에 object 기능을 추가하기 위해 사용합니다. 클래스 스코프 내의 특정 범위를 companion object 키워드의 코드 블록으로 감싸주면 그 안의 코드들을 인스턴스를 생성하지 않아도 사용할 수 있습니다.
  • 데이터 클래스는 간단한 값들의 저장을 위해 사용하는 클래스입니다. data class 키워드를 사용하며, 데이터 클래스를 정의할 때는 일반 클래스와 달리 생성자 파라미터 앞의 var(또는 val) 키워드를 생략할 수 없습니다. 주로 코드 블록을 사용하지 않고 간단하게 작성합니다.
    • 일반 클래스와 마찬가지로 인스턴스를 생성하여 사용하고, 변수와 마찬가지로 val 키워드가 사용된 파라미터들은 사용할 수 없습니다.
    • 일반 클래스에서 toString() 메서드를 호출하면 인스턴스의 주소 값을 반환하지만, 데이터 클래스는 값을 반환하기 때문에 실제 값을 모니터링하는데 사용합니다.
    • copy() 메서드를 사용하면 같은 값을 가지는 다른 인스턴스를 생성할 수 있습니다.
    • 데이터 클래스도 일반 클래스와 마찬가지로 init 블록과 메서드의 사용 등이 가능합니다.

Categories:

Updated:

Leave a comment