달나라 노트

Kotlin - Abstract class 본문

Kotlin

Kotlin - Abstract class

CosmosProject 2021. 3. 18. 03:26
728x90
반응형

 

 

 

 

Kotlin에서는 class를 생성할 때 여러 옵션을 줄 수 있는데 그 중 Abstract class라는 것에 대해 알아볼 예정입니다.

 

class FirstClass() {
    val var_test = "test"
}

class SecondClass(): FirstClass() {

}

위처럼 코드를 적으면 Error가 발생합니다.

 

Error message를 보면 아래와 같습니다.

This type is final, so it cannot be inherited from

 

이 Error가 일어나는 이유는 부모 class인 FirstClass가 open도 abstract도 아닌 일반 class이기 때문에 상속을 해줄 수 없기 때문입니다.

 

open class FirstClass() {
    val var_test = "test"
}

class SecondClass(): FirstClass() {

}

따라서 위처럼 open 키워드를 FirstClass에 붙여주면 위 Error는 해결됩니다.

 

 

 

open class FirstClass() {
    val var_test
}

class SecondClass(): FirstClass() {

}

.자 이제 위 코드를 봅시다.

결론부터 말하자면 위 코드는 Error를 발생시킵니다.

FirstClass가 부모 Class이고 FirstClass는 분명히 open class로 설정되어있는데 왜 Error가 뜰까요?

 

Property must be initialized or be abstract

 

Error message를 보면 위와 같습니다.

즉, 상속을 해 주는 부모 Class에 존재하는 어떤 내용이 initialize되지 않았기 때문에 발생하는 Error입니다.

 

FirstClass의 내용을 보면 var_test라는 변수가 선언만 되어있고 별다른 값이 assign되진 않고 있죠.

 

 

 

이러한 경우를 해결하려면 FirstClass의 속성을 abstract class로 변경해주면 됩니다.

 

abstract class FirstClass() {
    val var_test: String
}

class SecondClass(): FirstClass() {
    
}

따라서 위처럼 FirstClass에 abstract 키워드를 붙여줬습니다.

그러나 아직 Error가 발생합니다.

FirstClass의 var_test 변수에 위와 같은(Property must be initialized or be abstract) Error가 뜹니다.

그 이유는 class만 abstract로 만들어줬고 그 안에 생성되는 initialize 되지 않는 변수는 abstract로 설정하지 않았기 때문입니다.

 

 

abstract class FirstClass() {
    abstract val var_test: String
}

class SecondClass(): FirstClass() {

}

위처럼 코드를 수정해주면 이제 Error가 사라집니다.

근데 또 문제가 생겼습니다.

이번엔 SecondClass에서 Error가 발생했고 그 내용은 다음과 같습니다.

 

Class 'SecondClass' is not abstract and does not implement abstract base class member public abstract val var_test: String defined in FirstClass

 

이 Error는 SecondClass에서 상속받은 FirstClassdml var_test 변수에 값을 assign하지 않았기 때문에 발생합니다.

 

abstract class를 상속받은 자식 class는 반드시 부모의 abstract 속성에 값을 할당해야합니다.

 

 

abstract class FirstClass() {
    abstract val var_test: String
}

class SecondClass(): FirstClass() {
    override val var_test = "test"
}

따라서 위처럼 코드를 고치면 문제없이 실행됩니다.

근데 좀 이상합니다.

보통 상속받은 후에는 val_test = "test" 처럼만 적어도 될텐데 왜 SecondClass에서 다시 val_test 변수를 생성하고 override를 한 것일까요?

 

이것은 Kotlin의 규칙입니다.

abstract class를 상속받아서 abstract variable을 initialize할 때에는 자식 class에서 반드시 동일한 이름의 변수를 선언하여 override하는 방식으로 initialize를 해야합니다.

 

 

 

abstract class FirstClass() {
    abstract val var_test: String
}

class SecondClass(): FirstClass() {
    override val var_test = "test"
}

fun main() {
    val test = SecondClass()

    println(test.var_test)
}



-- Result
test

위 내용은 전체 code이며 잘 작동되는 것을 볼 수 있습니다.

 

 

 

 

 

 

abstract class FirstClass() {
    abstract val var_test: String
}

class SecondClass(): FirstClass() {
    override val var_test = "test"
}

fun main() {
    val test = FirstClass() // Error 발생

    println(test.var_test)
}

.위 코드를 봅시다.

위 코드는 이전의 예시와 동일하지만 main함수에서 test 변수에 객체를 생성하는 부분에 SecondClass 대신 FirstClass를 이용하였습니다.

그런데 이 부분에서 Error가 발생할겁니다.

에러메세지는 다음과 같습니다.

 

Cannot create an instance of an abstract class

 

에러메세지 그대로 abstract class를 직접적으로 이용하여 객체를 생성하는건 불가능하니 주의합시다.

 

 

 

 

 

 

그러면 왜 abstract class라는 개념이 필요한 것일까요?

 

코드를 작성하다보면 정말 다양한 경우를 코드 속에 담아야 하는 일이 생길겁니다.

그렇다면 class 속 모든 속성들을 100% 미리 정의해두고 사용해야 하는 경우'만' 생길까요?

아닐겁니다.

 

어떤 부모 class에 속성은 미리 설정해두면 좋겠는데 이 값이 너무 변칙적이어서 미리 설정해두기가 좀 애매한 경우가 있을 겁니다.

 

이런 경우 abstract class를 사용할 수 있습니다.

 

 

 

 

 

 

728x90
반응형
Comments