작성
·
639
답변 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.
라고 표현되어 있습니다 ㅎㅎㅎㅎ
항상 좋은 질문 남겨주셔서 감사합니다, 행복한 밤 되셔요!! 🙏🙇