[HeadFirst] Kotlin 추상 클래스

timothy jeong·2021년 10월 23일
0

코틀린

목록 보기
7/20

추상 클래스(Abstract)

이전 포스트에서 Animal 클래스를 만들고 이를 상속하는 Hippo 클래스를 만들었다. 그런데 여기서 Animal 클래스는 인스턴스화 되어도 괜찮을까? 코드를 작성한 본인은 "Animal 클래스는 당연히 인스턴스화 되면 안되!" 라고 말하겠지만, 다른 사람이라면 그 사실을 단번에 알아치리기는 힘들 것이다.

이렇게 Animal 처럼 상속체계에서는 필요하지만, 직접 인스턴스화 될 필요가 없는 클래스를 추상 클래스로 만들 수 있다. abstract 키워드 자체가 open 을 내포하고 있기 때문에 open 키워드를 추가할 필요가 없다.

abstract class Animal {
    ...
}

이러한 추상 클래스가 아닌 클래스를 모두 구상 클래스(concrete class) 라고 부른다. 어떤 클래스가 추상이 될지 구상이 될지는 개발되는 어플리케이션이 갖는 맥락에 따라 다르다. 나무 사전을 만드는 경우 Tree 는 추상 클래스가 되겠지만, 골프 게임을 만드는 경우 Tree 는 구상 클래스여야 할 것이다.

추상 프로퍼티, 추상 메서드

추상 클래스는 추상 혹은 추상이 아닌 프로퍼티와 메서드를 가질 수 있다.

abstract class Animal() {
    abstract val image: String
    abstract val food: String
    abstract val habitat: String
    var hunger = 10
    
    abstract fun eat()
}

다시 한번 Animal 클래스를 보자, 이제는 image, food, habitat 를 추상 프로퍼티로 만들었다. 추상 프로퍼티의 초기화에 대한 책임은 Animal 클래스를 상속한 최초의 구상 클래스에게 있다. (이 경우는 Hippo 다)

메서드도 추상화 시켰는데, 추상화된 메서드를 구현할 책임 역시 Animal 클래스를 상속한 최초의 구상 클래스에게 있다.

추상이 아닌 프로퍼티, 매서드들은 그대로 subClass 로 전달되며, open 인 경우 override 될 수 있다.

The Common Protocol

분명 상속은 common code 를 줄이기에 유용하다고 했는데, 추상 클래스에서 메서드를 추상화하여 그 구현 책임을 subClass 에 떠넘기는건 상속을 이용하는데 따른 이점을 잃어버리는게 아닐까?

그럼에도 불구하고 추상 클래스를 superClass 삼아 다형성을 구현하는 것은 여전히 유용하다. 많은 경우 개념적으로 동일하지만, 그 세부적인 동작 원리는 subClass 마다 다르기 때문에 오히려 common code로 superClass 에서 메서드로 구현할 수 있는 경우는 더 적다.

그러므로 차라리 개념적으로 묶여있는 객체들이 공통으로 가져야할 spec 을 추상 superClass 에서 정의해준다고 봐야한다. 이는 특정 subClass 그룹이 가져야하는 common protocol 을 만드는 샘이다.

추상 클래스의 상속

추상 클래스를 상속하는 구상클래스는 모든 추상 프로퍼티와 메서드를 구현해야한다.

class Hippo : Animal() {
    override var image = "hippo.jpg"
    override val food = "grass"
    override val habitat = "water"

    init {
        hunger = 11
    }

    override fun eat() {
        if (hunger < 0) {
            println("Hippos do not need to eat food.")
            return
        }
        println("The Hippo is eating $food")
        hunger--
    }
}

그에 반해 추상 클래스를 상속하는 추상 클래스는 추상 프로퍼티와 메서드를 구현할 수도 구현하지 않고 다음subClass 로 넘길 수도 있다.

custom getter, setter

추상 클래스에 custim getter 와 setter 를 설정할 수 있을까? 안된다. 어떤 프로퍼티나 메서드를 추상화 시킨다는 것은 컴파일러에게 해당 부분의 구현부를 subClass 로 넘긴다고 말하는 것이다. 그런데 custom getter, setter 는 구현을 따로 한 것에 해당하기 때문에 컴파일 에러가 발생한다.

profile
개발자

0개의 댓글