Groo

Kotlin 코틀린의 클래스와 객체 본문

프로그래밍 언어/Kotlin

Kotlin 코틀린의 클래스와 객체

김주엽 2020. 12. 30. 14:44

안녕하세요, 오늘은 Kotlin 코틀린 언어에서의 클래스와 객체에 대해서 알아보려고 합니다.
객체 지향 프로그래밍의 기본 개념과 여러 가지의 중요한 특징들에 대해서 살펴보도록 하겠습니다.

🌍 객체 지향 프로그래밍이란?

여러분들은 먼저 Kotlin 코틀린 언어가 객체 지향 프로그래밍과 함수형 프로그래밍을 동시에 접목한 다중 패러다임 언어라는 것을 알아두어야 하며 함수형 프로그래밍에 관련된 내용 같은 경우는 이전 글에 자세히 설명을 해두었으니 궁금하시다면 참고 부탁드립니다.

 

Kotlin 코틀린의 함수형 프로그래밍

안녕하세요 오늘은 Kotlin 코틀린 언어의 함수와 함수형 프로그래밍에 대해서 알아보도록 하겠습니다. 함수와 함수형 프로그래밍은 설명할 내용이 많아 내용들을 분할 시켜 여러 편으로 글을 작

juyeop.tistory.com

따라서 오늘은 Kotlin 코틀린의 객체 지향 프로그래밍에 대해 집중할 것이며 그중에서 클래스와 객체라는 주제에 대해서 상세히 알아볼 것입니다. 먼저 객체 지향 프로그래밍은 C++, Java, C# 등 많은 언어가 따르고 있는 프로그래밍 기법이며 실제 세계를 잘 모델링할 수 있다는 큰 장점이 존재해 대형 소프트웨어 설계에 적합하고 확장과 재활용이 용이해 현시대에 인기 있는 방법론 중 하나입니다.

 

앞으로 객체 지향 프로그래밍 기법으로 프로그램을 설계할 것이기에 아래와 같은 개념을 잘 알아두는 것이 중요합니다. 대부분의 객체 지향 프로그래밍 기법의 언어들은 이 모든 개념들이 도입되어 있으므로 이에 대해서는 지금부터 천천히 공부해보도록 하겠습니다.

 

추상화(Abstraction) : 특정 클래스를 만들 때 기본 형식을 규정하는 방법

인스턴스(Instance) : 클래스로부터 생성한 객체

상속(Inheritance) : 부모 클래스의 내용을 자식 클래스가 그대로 물려받음

다형성(Polymorphism) : 하나의 이름으로 다양한 처리를 제공

캡슐화(Encapsulation) : 내용을 숨기고 필요한 부분만 사용

메시지 전송(Message Sending) : 객체 간에 주고받는 메시지

연관(Association) : 클래스 간의 관계

🍄 Kotlin 코틀린에서 사용하는 용어는?

객체 지향 프로그래밍 기법이 발전되기 전까지는 같은 의미를 가진 특정 요소들의 용어가 통일되지 않고 각각의 언어 별로 약간 씩 다르게 사용되는 특징이 존재하고 있습니다. 그렇기에 Kotlin 코틀린의 객체 지향 프로그래밍에 관한 용어도 따로 구분되어 있습니다.

 

Kotlin 코틀린에서 사용하는 용어 다른 언어에서 사용하는 용어
클래스(Class) 분류, 범주
프로퍼티(Property) 속성(Attribute), 변수(Variable), 필드(Field), 데이터(Data)
메서드(Method) 함수(Function), 동작(Operation), 행동(Behavior)
객체(Object) 인스턴스(Instance)

객체 지향 프로그래밍 기법과 관련해 대표적인 용어 4가지가 존재합니다. 그중 프로퍼티 같은 경우는 보통 자바에서 클래스 내부에 포함된 변수를 필드라고 하는데 이 필드가 바로 Kotlin 코틀린에서 프로퍼티라는 용어로 불립니다. 그 이유는 Kotlin 코틀린과 같은 경우에는 클래스 내부에 포함된 변수 또는 필드에 내부적으로 접근 메서드가 자동으로 포함되어 있기 때문이라고 할 수 있습니다.

 

또한 클래스 내부에 포함될 수 있는 각종 요소들을 객체 지향 프로그래밍 기법에서는 멤버라는 용어로 통일하여 부르고 있으며 이 멤버에는 아래와 같이 다양한 종류의 요소들이 존재할 수 있습니다. 이들은 앞으로도 자주 언급될 것이기에 걱정하지 않으셔도 됩니다.

 

생성자와 초기화 블록 : 객체가 생성될 때 자동 실행되는 메서드 또는 코드 블록

프로퍼티 : 변수의 이름과 변수의 접근 함수가 포함된 형태

메서드 : 일반적인 함수의 형태

중첩 클래스와 이너 클래스 : 클래스 내부에 구성되는 클래스

객체 선언 : 클래스 없이 접근할 수 있는 객체

💬 통합 모델링 언어란?

통합 모델링 언어는 Unified Modeling Language를 줄여서 UML이라고 부릅니다. 즉 UML은 객체 지향 프로그램 설계를 위한 다이어그램 표기법으로 개발 단계에서 팀의 의사소통을 원활히 하는데 많은 도움을 주며 여러 종류의 다이어그램 기법이 존재합니다.

 

클래스 다이어그램 : 클래스의 정의와 관계를 나타내는 다이어그램

시퀀스 다이어그램 : 시간의 개념을 통해 클래스에서 생성된 객체의 실행 흐름을 나타냄

유스 케이스 다이어그램 : 사용자 관점에서 사용 방법에 대해 설명

상태 머신 다이어그램 : 시스템 관점에서 상태가 어떻게 변화하는지 나타냄

통합 모델링 언어에 관련해 대표적인 다이어그램 4가지가 존재합니다. 각각의 다이어그램은 통합 모델링 언어를 사용해야 하는 시점의 배경과 사용 용도를 잘 파악하여 올바른 다이어그램을 선택해 활용한다면 보다 더 효과적인 프로그램 설계가 가능할 것입니다.

📸 클래스, 객체, 인스턴스란?

객체 지향 프로그래밍에 관련된 다양한 개념들을 자세히 알아보기 전 위의 3가지 키워드를 확실히 이해하는 것이 중요합니다. 먼저 클래스라는 것은 특정한 객체를 생성하기 위한 일종의 틀을 의미하며 실제 메모리 상에 실행되고 있는 존재가 아닙니다. 그렇다면 반대로 객체라는 것은 앞에서의 클래스라는 개념의 실체로서 물리적인 메모리 영역에 실행되고 있는 존재라고 말할 수 있습니다.

 

즉 클래스라는 틀을 기반으로 만들어진 요소를 실질적인 메모리 영역에 실행되고 있는 객체라고 부르며 이러한 과정을 객체 지향 프로그래밍에서는 인스턴스화 되었다고 말합니다. 또한 클래스로부터 만들어진 객체는 그 클래스의 인스턴스라고 부릅니다. 객체와 인스턴스는 거의 유사한 것 같지만 객체를 현실의 대상에 비유하자면 인스턴스는 객체를 소프트웨어 세계에 실체화한 것입니다.

🎨 클래스의 추상화란?

실제 세계에서 사람들은 특정 대상을 이해할 때 각각의 특징이나 행동 방식을 기록해서 이름을 붙이고 개념을 정의합니다. 이러한 방식을 소프트웨어 세계에 비유한다면 특정한 클래스에 필요한 속성과 동작을 정의하는 과정으로 이를 클래스의 추상화라고 합니다.

 

이해를 돕기 위해 간단한 예시를 들어보겠습니다. Student라는 특정 클래스를 추상화하는 과정 속에서 프로퍼티는 name, age, height, gender가 존재할 수 있으며 메서드로는 run( ), jump( ), sing( ), study( ) 등이 존재할 수 있는 것을 생각할 수 있습니다.

class Student {
    var name: String = "김주엽"
    var age: Int = 18
    var height: Int = 172
    var gender: Boolean = false

    fun run() = println("$name 달립니다.")
    fun jump() = println("$name 점프합니다.")
    fun sing() = println("$name 노래합니다.")
    fun study() = println("$name 공부합니다.")
}

다시 한번 정리해 클래스의 추상화라는 것은 특정 클래스에 필요할 것 같은 프로퍼티, 메서드 등을 생각해보면서 정의하는 과정이라고 할 수 있습니다. 또한 이 과정 속에서 아래와 같이 클래스 다이어그램을 활용하여 설계한다면 추상화에 많은 도움이 될 것입니다.

 

📬 클래스의 생성자란?

생성자란 클래스를 통해 객체가 만들어질 때 기본적으로 호출되는 함수를 뜻합니다. 이 생성자 함수에서는 외부로부터 객체를 생성할 때 필요로 하는 값을 인자로 전달받아 클래스 내부의 각종 프로퍼티 값을 초기화할 수 있습니다. 대체적으로 생성자 함수에서는 값 초기화 역할을 많이 담당하고 있으며 주 생성자와 부 생성자 2가지 종류가 존재하므로 필요에 따라 원하는 것을 사용할 수 있습니다.

# 부 생성자

부 생성자는 클래스 내부의 일반 메서드처럼 동일하게 선언 가능합니다. 그러나 메서드를 의미하는 fun 키워드를 사용하지 않고 생성자의 constructor라는 고유 키워드를 사용해 부 생성자를 구현합니다. 아래의 예시 코드를 보면 이전과는 달리 Student 클래스의 프로퍼티를 선언만 하고 초기화는 부 생성자의 매개변수로 전달받은 값을 통해 생성자 함수에서 초기화하는 것을 볼 수 있습니다.

class Student {
    var name: String
    var age: Int
    var height: Int
    var gender: Boolean

    constructor(_name: String, _age: Int, _height: Int, _gender: Boolean) {
        name = _name
        age = _age
        height = _height
        gender = _gender
    }

    fun run() = println("$name 달립니다.")
    fun jump() = println("$name 점프합니다.")
    fun sing() = println("$name 노래합니다.")
    fun study() = println("$name 공부합니다.")
}

또한 Kotlin 코틀린에서는 클래스 내부에 부 생성자를 여러 개 포함할 수 있습니다. 그 조건은 부 생성자의 매개변수 수 또는 각각의 자료형을 다르게 구성하면 추후에 배울 오버로딩의 개념이 도입되어 부 생성자를 여러 개 추가 가능합니다. 하지만 여기서 정말 중요한 점은 클래스 내부의 프로퍼티를 선언만 하고 초기화해주지 않았다면 부 생성자에서 이를 무조건 초기화해주어야 하는 것입니다.

class Student {
    var name: String
    var age: Int
    var height: Int
    var gender: Boolean

    constructor(_name: String, _age: Int, _height: Int, _gender: Boolean) {
        name = _name
        age = _age
        height = _height
        gender = _gender
    }

    constructor(_name: String, _gender: Boolean) {
        name = _name
        age = 18
        height = 172
        gender = _gender
    }

    fun run() = println("$name 달립니다.")
    fun jump() = println("$name 점프합니다.")
    fun sing() = println("$name 노래합니다.")
    fun study() = println("$name 공부합니다.")
}

# 주 생성자

클래스 생성자로 많이 사용되고 있는 방법인 주 생성자는 클래스 이름과 함께 생성자 정의를 이용할 수 있는 기법입니다. 주 생성자는 클래스 이름과 블록 시작 부분 사이에 선언합니다. 주 생성자도 부 생성자와 마찬가지로 constructor 키워드를 이용해 생성자를 선언하나 추후에 배울 가시성 지시자나 애노테이션 표기가 클래스 선언에 존재하지 않는다면 constructor 키워드를 생략 가능합니다.

 

또한 아래의 코드를 보면 클래스 내부에 존재하는 각각의 프로퍼티들은 주 생성자의 매개변수로 전달받은 인자들을 통해 선언과 동시에 값을 초기화하는 모습을 볼 수 있습니다. 앞에서 배웠던 부 생성자와 비교했을 때 상대적으로 더 간편한 것을 볼 수 있습니다.

class Student(_name: String, _age: Int, _height: Int, _gender: Boolean) {
    var name: String = _name
    var age: Int = _age
    var height: Int = _height
    var gender: Boolean = _gender

    fun run() = println("$name 달립니다.")
    fun jump() = println("$name 점프합니다.")
    fun sing() = println("$name 노래합니다.")
    fun study() = println("$name 공부합니다.")
}

더 나아가 위의 코드를 조금 더 간편하게 하기 위해 Kotlin 코틀린은 클래스 내부의 프로퍼티를 생략하고 생성자의 매개변수에 프로퍼티 표현을 함께 넣을 수 있는 기능을 제공하고 있습니다. 즉 클래스 내부의 프로퍼티 선언을 생성자 매개변수에 대신하는 것이라고 말할 수 있습니다. 하지만 이 기능은 주 생성자에서만 가능하며 앞에서 배운 부 생성자에서는 불가능한 것을 기억해주시기 바랍니다. 이 기능을 통해 매개변수로 전달받은 값을 기존의 프로퍼티에 재초기화하는 불필요한 작업을 생략할 수 있다는 것이 큰 장점입니다.

class Student(val name: String, val age: Int, val height: Int, val gender: Boolean) {
    fun run() = println("$name 달립니다.")
    fun jump() = println("$name 점프합니다.")
    fun sing() = println("$name 노래합니다.")
    fun study() = println("$name 공부합니다.")
}

그러나 부 생성자와 같은 경우는 일반적인 메서드와 같은 형태이기에 값 초기화뿐만 아니라 특정 함수 호출 등 다양한 기능을 구현할 수 있습니다. 마찬가지로 주 생성자 또한 값 초기화뿐만 아니라 다양한 기능 구현이 가능하나 생성자 자체에서는 불가능해 Kotlin 코틀린에서 제공하는 초기화 블록인 init을 통해 기능을 구현할 수 있습니다. init과 같은 경우는 주 생성자와 부 생성자 모두 함께 사용할 수 있습니다. 그러나 부 생성자와 init을 함께 사용할 경우 부 생성자보다 init 블록이 먼저 선언되는 것을 주의해야 합니다.

class Student(val name: String, val age: Int, val height: Int, val gender: Boolean) {
    init {
        println("init 초기화 블록 호출됩니다.")
    }

    fun run() = println("$name 달립니다.")
    fun jump() = println("$name 점프합니다.")
    fun sing() = println("$name 노래합니다.")
    fun study() = println("$name 공부합니다.")
}

👨‍👩‍👧‍👦 클래스의 상속이란?

클래스는 자식 클래스를 만들 때 부모 클래스의 속성과 기능을 물려받아 계승하는데 이것을 상속이라고 합니다. 상속을 이용하면 하위 클래스는 또 다시 상위 클래스의 모든 내용을 구현하지 않고도 상위 클래스에 존재하는 프로퍼티 및 메서드를 접근할 수 있습니다.

 

또한 Kotlin 코틀린의 모든 클래스는 따로 상위 클래스를 명시하지 않으면 기본적으로 Any 클래스의 하위 클래스가 되는 구조입니다. 만약 하위 클래스가 특정 상위 클래스를 상속할 수 있도록 하기 위해서는 상위 클래스에 open 키워드를 꼭 추가하여야만 합니다.

 

이해를 돕기 위해 간단한 예시를 들어보겠습니다. 아래의 사진은 클래스 다이어그램 방식으로 예제 프로그램을 설계한 것입니다. 현재 Chicken 클래스는 Food 클래스를 상속하고 있기 때문에 Food 클래스에 존재하는 각종 프로퍼티와 메서드들을 자유롭게 참조할 수 있습니다. 또한 하위 클래스는 클래스 내부에 marker 프로퍼티와 fry( ) 메서드를 추가적으로 구성한 모습을 볼 수 있습니다.

 

즉 클래스 상속의 기능을 활용하면 하위 클래스는 상위 클래스의 메서드나 프로퍼티를 그대로 참조하면서 상위 클래스에 없는 자신만의 프로퍼티나 메서드를 확장하여 구현하면 되니 훨씬 효율적이고 체계적인 프로그램 구조가 이루어질 것입니다. 단 클래스 상속이 이루어지는 하위 클래스 및 상위 클래스는 서로 간에 연관되는 특징이 존재해야만 상속의 개념에 적합하니 이점 꼭 유의 바랍니다.

open class Food(var name: String, var price: Int) {
    fun sell() = println("$name 판매합니다.")
}

class Chicken(var maker: String) : Food("고추 바사삭", 16000) {
    fun fry() {
        println("$name 튀깁니다.")
        sell()
    }
}

🧭 클래스의 다형성이란?

클래스를 상속하다 보면 때로는 같은 이름이지만 매개변수를 다르게 하거나 아예 기능 구현부를 다르게 작성할 필요가 생길 수 있습니다. 이렇듯 이름은 동일하지만 매개변수가 서로 다른 형태를 취하거나 실행 결과를 다르게 가질 수 있는 것을 다형성이라고 합니다.

 

대표적인 다형성의 종류로는 2가지가 존재합니다. 첫 번째는 하는 동작은 동일하나 입력 인자의 형식이 다른 오버로딩이며 두 번째는 입력 인자의 형식은 동일하나 하는 동작이 다른 오버라이딩이 존재합니다. 지금부터 각각에 대해서 자세히 알아보도록 하겠습니다.

# 오버로딩

오버로딩은 동일한 클래스 안에서 같은 이름의 메서드가 매개변수만 달리해 여러 번 정의될 수 있는 개념으로 반환 값은 동일하거나 달라질 수 있습니다. 그러나 구현되는 동작은 동일해야 합니다. 아래의 코드 속 add 메서드는 매개변수로 전달받은 값을 모두 더해 다시 반환하는 구조로 구현 동작은 동일하나 메서드의 매개변수 수와 형식이 조금씩 달라 여러 개의 메서드를 정의했습니다. 이처럼 오버로딩을 사용하면 같은 이름의 메서드로 다양한 인자를 처리할 수 있기 때문에 메서드를 손쉽게 확장할 수 있는 장점이 있습니다.

class Calculation {
    fun add(x: Int, y: Int): Int = x + y
    fun add(x: Double, y: Double): Double = x + y
    fun add(x: Int, y: Int, z: Int): Int = x + y + z
    fun add(x: String, y: String): String = x + y
}

# 오버라이딩

오버라이드란 사전적 의미로 중단하다 또는 뒤엎다 등으로 해석할 수 있습니다. 즉 상위 클래스의 특정 프로퍼티나 메서드를 하위 클래스에서 새롭게 재정의하는 것입니다. 이 과정에서 오버로딩과 반대로 구현되는 동작은 달라질 수 있으나 메서드의 이름이나 매개변수 및 반환 값은 이전과 동일해야 합니다. Kotlin 코틀린에서는 상위 클래스의 내용을 하위 클래스가 오버라이딩할 수 있도록 하기 위해 오버라이딩을 허용하는 프로퍼티 또는 메서드에 open 키워드를 그리고 하위 클래스에서는 override 키워드를 각각 사용합니다. 

 

아래의 코드 속 현재 Human 클래스는 상위 클래스이며 sing( ) 메서드를 하위 클래스에서 오버라이딩 할 수 있도록 open 키워드를 추가해 선언했습니다. 반면에 Singer 클래스는 Human 클래스를 상속하는 하위 클래스이며 Human 클래스의 sing( ) 메서드를 오버라이딩하여 메서드의 이름이나 매개변수 및 반환 값은 동일하지만 구현되는 동작은 다르게 하였습니다. 이처럼 오버라이딩은 하위 클래스에서 특정 메서드를 재설계할 때 유용한 기법으로 유연하면서도 사용하기 쉬운 메서드를 설계할 수 있다는 장점이 있습니다.

open class Human {
    open fun sing() = println("노래를 부른다.")
}

class Singer : Human() {
    override fun sing() = println("노래를 잘 부른다.")
}

📊 super와 this의 참조란?

상속 기능을 활용하여 클래스를 상위와 하위 클래스로 설계하다 보면 상위와 현재 클래스의 생성자나 특정 프로퍼티 및 메서드를 참조해야 하는 경우가 생깁니다. 이런 경우를 대비해 상위 클래스는 super 키워드로 현재 클래스는 this 키워드로 참조가 가능합니다.

 

super 키워드 this 키워드
super( ) this( )
super.프로퍼티 이름 this.프로퍼티 이름
super.메서드 이름( ) this.메서드 이름( )

# 상위 클래스 참조

하위 클래스에서 상위 클래스의 메서드를 오버라이딩하려고 할 때 만일 상위 클래스에서 구현한 내용을 그대로 사용하고 아래에 필요한 내용만 추가하고 싶을 수도 있습니다. 이때 상위 클래스를 가리키는 특별한 키워드 super를 사용하면 이를 구현할 수 있습니다.

open class Human {
    open fun sing() = println("노래를 부른다")
}

class Singer : Human() {
    override fun sing() {
        super.sing()
        println("가수이다 보니 노래를 잘 부른다")
    }
}

# 현재 클래스 참조

현재 클래스 참조 역시 super 키워드와 같이 this 키워드라는 것이 존재하며 이 this 키워드를 통해 현재 클래스의 생성자나 특정 프로퍼티 및 메서드를 참조할 수 있습니다. 아래의 코드는 동일한 클래스의 특정 부 생성자에서 다른 부 생성자를 접근하는 것입니다.

class Human {
    var name: String
    var age: Int
    
    constructor(_name: String) : this(_name, 18)
    constructor(_name: String, _age: Int) {
        name = _name
        age = _age
    }
}

# 바깥 클래스 참조

클래스 안에 다시 클래스를 선언하는 것이 가능합니다. 이때 만약 inner 키워드와 함께 클래스를 선언했다면 이는 바깥 클래스의 상위 클래스를 접근할 수 있습니다. 만약 내부 클래스에서 바깥 클래스를 참조하려면 바깥 클래스의 이름으로 참조가 가능하며 더 나아가 바깥 클래스의 상위 클래스를 참조하려면 super 키워드와 함께 @ 기호 옆에 바깥 클래스 이름을 작성하여 참조할 수 있습니다.

open class Parent {
    open fun speak() = println("나는 부모입니다.")
}

class Child : Parent() {
    override fun speak() = println("나는 자식입니다.")

    inner class Baby {
        fun speak() = println("나는 아기입니다.")
        fun access() {
            speak()
            Child().speak()
            super@Child.speak()
        }
    }
}

# 인터페이스 참조

Kotlin 코틀린은 하나의 클래스에 상위 클래스 한 개를 상속할 수 있으며 추가적으로 여러 개의 인터페이스를 지정해 구현할 수 있습니다. 그러므로 상위 클래스와 인터페이스에 존재하는 프로퍼티나 메서드의 이름이 서로 중복될 수 있습니다. 만일에 동일한 이름의 프로퍼티나 메서드가 있다면 앵글 브래킷을 활용해 접근하려는 클래스나 인터페이스를 직접적으로 지정하여 참조할 수 있습니다.

open class Product {
    open fun action() = println("상품을 동작시킵니다.")
}

interface Electronics {
    fun action() = println("전자제품을 동작시킵니다.")
}

class Computer : Product(), Electronics {
    override fun action() = println("컴퓨터를 동작시킵니다.")

    fun access() {
        action()
        super<Product>.action()
        super<Electronics>.action()
    }
}

💰 정보은닉 캡슐화란?

프로그래밍을 하다 보면 특정 클래스를 작성할 때 외부에서 참조 및 접근을 해야 하는 속성이나 기능이 있는 반면에 굳이 접근할 필요가 없는 속성이나 기능이 존재할 수도 있습니다. 이러한 개념을 정보은닉의 캡슐화라고 하며 객체 지향 프로그래밍의 가장 큰 특징이기도 합니다. 이처럼 캡슐화를 도와주는 기능으로는 가시정 지시자로서 Kotlin 코틀린에서는 대표적인 4가지를 제공하고 있습니다.

 

이 4가지의 가시정 지시자는 전역 변수, 함수, 클래스, 프로퍼티, 메서드, 인터페이스 등에 붙여서 사용할 수 있습니다. 만약 가시정 지시자를 선언하지 않으면 public 지시자가 기본값이 됩니다. 각각의 지시자를 특정 상황과 사용 용도에 맞게 잘 활용하시기 바랍니다.

 

private : 이 요소는 외부에서 접근할 수 없다

protected : 외부에서 접근할 수 없으나 하위 상속 요소에서는 접근이 가능하다

internal : 같은 정의의 모듈 내부에서는 접근이 가능하다

public : 이 요소는 어디서든 접근이 가능하다 (기본값)

🧲 클래스와 클래스 간의 관계

프로그래밍을 할 때 만약 클래스가 하나만 존재하는 경우에는 할 수 있는 게 많이 존재하지 않습니다. 그러나 클래스의 수가 많아진다면 클래스와 클래스 간의 관계가 형성될 것이고 메시지 전송 등 다양한 기능들을 구현함에 따라 복잡한 현실 세계와 비슷하게 프로그래밍을 설계할 수 있을 것입니다. 대표적으로 Kotlin 코틀린은 클래스와 클래스의 관계에 관한 핵심 4가지를 정의하고 있습니다.

 

연관(Association) : 서로 분리된 클래스가 연결을 가지는 것이다 (약한 참조 + 생명주기 다르다)

의존(Dependency) : 한 클래스가 다른 클래스에 의존되어 있다 (약한 참조 + 생명주기 다르다)

집합(Aggregation) : 한 클래스가 특정 클래스를 소유한다 (강한 참조 + 생명주기 다르다)

구성(Composition) : 특정 클래스가 한 클래스의 부분이다 (강한 참조 + 생명주기 같다)

👍 글을 마치며

이렇게 오늘 글의 주제인 Kotlin 코틀린의 클래스와 객체에 관한 설명을 모두 마쳤습니다. 처음에는 이만큼의 분량을 기대하고 작성을 하지 않았으나 객체 지향 프로그래밍과 클래스 및 객체를 접목해 설명하다 보니 분량이 생각 의외로 많이 늘어난 것 같습니다. 위의 모든 내용을 한 개씩 공부하려고 하지 말고 자신에게 필요한 정보만 골라서 공부하는 것도 좋은 방법일 것이라고 생각합니다. 혹시나 위의 내용에서 잘못된 내용이 존재하거나 피드백이 있다면 댓글로 남겨주시면 빠르게 확인해 답변하도록 하겠습니다. 감사합니다.

 

참고 : Do it 코틀린 프로그래밍

Comments