[kotlin] 코틀린에서 상속을 이용한 코드 재사용성 향상 방법

코틀린은 객체 지향 프로그래밍 언어로서 상속을 지원합니다. 상속을 제대로 활용함으로써 코드의 재사용성을 향상시킬 수 있습니다. 이번 포스트에서는 코틀린에서 상속을 이용한 코드 재사용성 향상 방법에 대해 알아보겠습니다.

1. 상속을 통한 기본 구현 제공

상속을 이용하여 부모 클래스에 기본 구현을 제공하고, 자식 클래스에서 필요에 따라 구현을 변경할 수 있습니다. 이렇게 함으로써 개발자는 공통 로직을 부모 클래스에서 관리하고, 자식 클래스에서는 확장 및 변경된 로직만을 구현하면 됩니다.

open class Shape {
    open fun draw() {
        println("Shape is being drawn")
    }
}

class Circle : Shape() {
    override fun draw() {
        println("Circle is being drawn")
    }
}

class Rectangle : Shape() {
    override fun draw() {
        println("Rectangle is being drawn")
    }
}

위 예제에서 Shape 클래스는 기본적인 도형을 그리는 기능을 가지고 있습니다. CircleRectangle 클래스는 Shape 클래스를 상속받아 그림을 그리는 기능을 확장하고, 각각 원과 사각형을 그릴 수 있도록 구현합니다.

2. 상속을 통한 다형성 활용

상속을 통해 다형성을 활용할 수 있습니다. 다형성은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 하나의 메서드가 여러 타입을 처리할 수 있는 능력을 의미합니다. 이를 통해 코드를 유연하게 작성할 수 있고, 코드 재사용성을 향상시킬 수 있습니다.

open class Animal {
    open fun makeSound() {
        println("The animal makes a sound")
    }
}

class Dog : Animal() {
    override fun makeSound() {
        println("The dog barks")
    }
}

class Cat : Animal() {
    override fun makeSound() {
        println("The cat meows")
    }
}

fun main() {
    val animals = listOf(Animal(), Dog(), Cat())
    for (animal in animals) {
        animal.makeSound()
    }
}

위 예제에서 Animal 클래스는 동물의 소리를 내는 기능을 가지고 있습니다. DogCat 클래스는 각각 개와 고양이의 소리를 내는 기능을 확장하고 있습니다. main 함수에서는 Animal 및 그 자식 객체들을 리스트로 저장하고 각 객체의 makeSound 메서드를 호출합니다. 이때, 각각의 객체에 맞는 makeSound 구현이 호출되어 다형성을 활용한 코드 재사용성이 가능합니다.

3. 상속을 통한 인터페이스의 활용

상속을 통해 인터페이스의 활용도 높일 수 있습니다. 인터페이스는 클래스가 구현해야 할 메서드를 정의하는 역할을 합니다. 상속을 통해 여러 클래스가 동일한 인터페이스를 구현할 수 있으며, 이를 통해 코드 재사용성을 높일 수 있습니다.

interface Playable {
    fun play()
}

open class Instrument {
    open fun tune() {
        println("Instrument is being tuned")
    }
}

class Piano : Instrument(), Playable {
    override fun tune() {
        println("Piano is being tuned")
    }

    override fun play() {
        println("Piano is being played")
    }
}

class Flute : Instrument(), Playable {
    override fun tune() {
        println("Flute is being tuned")
    }

    override fun play() {
        println("Flute is being played")
    }
}

fun main() {
    val instruments = listOf(Piano(), Flute())
    for (instrument in instruments) {
        instrument.tune()
        if (instrument is Playable) {
            instrument.play()
        }
    }
}

위 예제에서 Playable 인터페이스는 play 메서드를 정의하고 있습니다. Instrument 클래스는 악기의 튜닝 기능을 가지고 있으며, PianoFlute 클래스는 각각 Instrument 클래스를 상속받고 Playable 인터페이스를 구현하고 있습니다. main 함수에서는 악기를 리스트로 저장하고 각 악기의 튜닝 기능과 (Playable 인터페이스를 구현한 경우) 플레이 기능을 호출합니다.

결론

코틀린에서 상속을 이용하여 코드 재사용성을 향상시킬 수 있습니다. 상속을 통해 기본 구현 제공, 다형성 활용, 인터페이스 활용 등 다양한 방법을 적용할 수 있습니다. 상속을 올바르게 활용하면 유연하고 확장 가능한 코드를 작성할 수 있습니다.