평상시에 코틀린 파일을 디컴파일하면서 final로 선언되어있는 코드를 보면서 의문만 가지고 이유에 대해서 찾아보지 못하다가 이번 기회에 코틀린에서 default가 final인 이유에 대해서 찾아보았습니다.
제가 생각했을 때는 크게 두가지 이유가 있습니다.
첫번째는 코틀린은 함수형 프로그래밍에서 아이디어를 얻어왔고 가변을 사용했을 때 발생하는 문제점들을 줄이기 위해 불변을 사용합니다. 그래서 모든 클래스들이 기본값으로 final로 선언되어 있는 이유기도 합니다.
두번째는 상속에대한 문제입니다.
코틀린 공식 문서에 상속을 설명하는 부분을 보면 다음과 같은 문구가 있습니다.
By default, Kotlin classes are final – they can't be inherited. To make a class inheritable, mark it with the
open
keyword:
코틀린 클래스는 기본적으로 final이며 이는 상속이 불가능하게 합니다. 만약 상속이 가능하게 하려면 open
키워드를 써야합니다. 라고 설명되어있습니다.
객체지향 관점에서 상속은 개발자들이 아직까지도 올바르게 사용하지 못하는 실수들을 하곤합니다. 무분별한 상속은 객체지향의 의도나 목적과는 반대로 설계할 가능성이 있습니다.
스택오버플로에서 상속보다 구성을 선호하는 원칙에 대해서 오래전 부터 논의한 내용이 있습니다. 그래서 제가 생각하기에는 코틀린은 클래스에 대해서 기본값을 final로 설정을하고 개발자들이 어떠한 문제를 마주했을 때 이 문제를 해결하기 위해서 상속을 사용하는 것 보다 더 나은 방법으로 문제를 해결할 수 있게 생각해보라는 의미로도 해석해 볼 수 있을 것 같습니다.
실제 글 작성 기준인 2023년 1월 28일 기준으로 코틀린 discuss의 Classes final by default 글에서 178명의 투표로 final이 52%, open이 48%로 비슷한 비율로 투표가 유지되고 있습니다.
final 키워드는 프로퍼티 값을 Immutable하게 만들거나 클래스나 메서드를 상속이나 오버라이드 하지 못하게 만드는 특징이 있습니다. 그렇기 때문에 런타임에 다형성을 체크하지 않아 성능상의 약간의 이점을 가져갈 수 도 있습니다.