[kotlin] 코틀린에서 추상 클래스와 인터페이스를 선택하는 기준

코틀린은 자바와 같이 추상화를 위해 추상 클래스와 인터페이스를 제공합니다. 두 가지 방법 모두 코드의 재사용성과 유연성을 높여주는 중요한 요소입니다. 하지만 어떤 경우에는 추상 클래스를 사용하는 것이 좋을지, 어떤 경우에는 인터페이스를 사용하는 것이 좋을지 판단하기가 어렵습니다. 이번 글에서는 코틀린에서 추상 클래스와 인터페이스를 선택하는 기준을 알아보겠습니다.

1. 추상 클래스

추상 클래스는 일반 클래스와 마찬가지로 상태와 메소드를 가지며, 일부 메소드는 구현되어 있고 일부는 추상 메소드로 선언됩니다. 이 추상 클래스를 상속받은 클래스는 반드시 추상 메소드를 구현해야 합니다.

추상 클래스를 선택하는 경우는 다음과 같습니다:

예를 들어, 동물 클래스를 상속받은 고양이와 개 클래스를 생성한다고 가정해 봅시다. 동물 클래스는 이 두 클래스에게 공통적인 동작을 제공하며, 추상 메소드로 애완동물의 울음소리를 가져오는 getSound 메소드를 선언할 수 있습니다.

abstract class Animal {
    abstract fun getSound(): String
}

class Cat : Animal() {
    override fun getSound(): String {
        return "야옹"
    }
}

class Dog : Animal() {
    override fun getSound(): String {
        return "멍멍"
    }
}

2. 인터페이스

인터페이스는 클래스의 동작을 정의하는 구조입니다. 인터페이스는 추상 메소드와 프로퍼티를 선언할 수 있으며, 클래스에서 이를 구현해야 합니다. 인터페이스는 여러 개를 동시에 구현할 수 있고, 클래스 내부에 있는 다른 클래스처럼 동작할 수 있습니다.

인터페이스를 선택하는 경우는 다음과 같습니다:

예를 들어, 사자와 호랑이 클래스가 사냥하는 행동을 가지고 있다고 가정해 봅시다. 이러한 사냥 행동을 나타내는 Hunt 인터페이스를 정의하고, 사자와 호랑이 클래스에서 이를 구현할 수 있습니다.

interface Hunt {
    fun hunt()
}

class Lion : Hunt {
    override fun hunt() {
        println("사자가 사냥을 합니다.")
    }
}

class Tiger : Hunt {
    override fun hunt() {
        println("호랑이가 사냥을 합니다.")
    }
}

결론

추상 클래스와 인터페이스는 코틀린에서 코드 재사용성과 유연성을 높이는데 중요한 역할을 합니다. 추상 클래스는 상속을 통해 공통된 동작을 제공하고, 인터페이스는 클래스 간의 동작을 정의하는데 사용됩니다. 적절한 상황에서 추상 클래스와 인터페이스를 선택하여 코드를 설계하는 것이 중요합니다.