인프런 커뮤니티 질문&답변

이용조님의 프로필 이미지

작성한 질문수

자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide)

10강. 코틀린에서 상속을 다루는 방법

상위클래스의 생성자나 init블럭에서 final이 아닌 프로퍼티에 접근하지 말라 의미여

작성

·

630

2

안녕하세요.

derived클래스에서 number 0나오는 예제 있잖아여

상위클래스의 생성자나 init블럭에서 final이 아닌 프로퍼티에 접근하면 안된다고 하셨는데

 

final이라고 해서 var이아닌 val인가? 처음에 생각했는데

저 의미가 아니라

정확히는 open키워드로 상속을 열어둬서 하위클래스에서 오버라이딩 될 수 있는 프로퍼티에 접근하지 말라는거죠?

자바에선 메쏘드에 final 키워드를 붙이면 하위클래스에서 오버라이딩이 불가능 하니깐 사용하신 의미라 생각되는데 좀 햇갈려서요~

 

감사합니다.

 

답변 4

3

number 를 계속 필드라고 생각해서 혼동됐는데

Base 클래스의 init 구문에서 사용되는 number 는 getter 라고 생각하니까 이해가 됐습니다..!

(혹시 저 처럼 헷갈리시는 분들을 위해)

 

open class Base(
    open val num: Int = 100
) {
    init {
        println("Base init")
        println(this.num) // Derived.getNum()
    }
}

class Derived(
    num: Int
) : Base(num) {
    override val num: Int = num
        get() {
            println("Derived getter")
            return field
        }
    init {
        println("Derived init")
        println(this.num)
    }
}

fun main() {
    Derived(300)
}

------- Result ------
출력 결과는 다음과 같음
    Base 의 init 에서 호출하는 num 은 getter 인데, 이 getter 는 Derived 에서 override 되었음
    그런데 Derived 의 num getter 에서 반환하는 field 는 아직 초기화되지 않아 Int 기본값 0을 반환
    그래서 Base 의 this.num 에서는 반환받은 0을 출력함

Base init
Derived getter
0
Derived init
Derived getter
300

1

이용조님의 프로필 이미지
이용조
질문자

강의 뒤에 내용이 좀더 있었군요 맞는것 같습니다.

0

저도 이부분이 굉장히 혼란스러웠는데, 진완님이 number필드가 아닌 getter 호출이라는 부분을 한 번 더 짚어주어 이해에 큰 도움이 되었습니다!

감사합니다!!

0

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요 용조님~!! 크으~ 좋은 포인트이십니다!! 😊😊

 

네네, 정확히 맞습니다!! final이 아닌 이라고 표현한 부분은 open 키워드로 상속을 열어 하위 클래스에 오버라이딩 될 수 있는 프로퍼티에 접근하면 안된다 라는 의미입니다!!

 

프로퍼티가 오버라이딩 된다는 것을 Java로 표현하면 getter를 (var의 경우 setter)까지 오버라이드 한다는 것으로 메소드에 대한 오버라이딩이 되니까요!

 

추가로 보다 정확한 내용은 https://kotlinlang.org/docs/inheritance.html#derived-class-initialization-order 에서 확인하실 수 있습니다!

 

Using any of those properties in the base class initialization logic (either directly or indirectly through another overridden open member implementation) may lead to incorrect behavior or a runtime failure. When designing a base class, you should therefore avoid using open members in the constructors, property initializers, or init blocks.

 

라고 표현되어 있습니다 ㅎㅎㅎㅎ

항상 좋은 질문 남겨주셔서 감사합니다, 행복한 밤 되셔요!! 🙏🙇