상속, 인터페이스, 접근 제어
작성
step 10(상속)과 11(접근 제어)에서 적은 것이다.
추상 클래스와 상속
abstract class KotlinAnimal(
protected val species: String,
protected open val legCount: Int, // 추상 프로퍼티가 아니면 상속받아 바꾸려 할 때 open 을 붙인다
) {
abstract fun move()
}
class KotlinCat(
species: String
) : KotlinAnimal(species, 4) {
override fun move() {
println("고양 고양")
}
}
- 상속과 구현 모두
:를 쓴다. 컨벤션은:양쪽에 공백을 둔다. - 상위 클래스를 상속할 때 상위 클래스의 생성자를 바로 호출해야 한다.
- 오버라이드할 때는
override를 반드시 붙인다.
상속 관련 키워드
final: 오버라이드할 수 없다. 기본값이다.open: 오버라이드를 열어 준다.abstract: 반드시 오버라이드해야 한다.override: 상위 타입을 오버라이드하고 있음을 나타낸다.
인터페이스
interface KotlinFlyable {
// default 키워드 없이 메서드를 구현할 수 있다
fun act() {
println("파닥파닥")
}
}
interface KotlinSwimable {
fun act() {
println("어푸어푸")
}
}
class KotlinPenguin(
species: String
) : KotlinAnimal(species, 2), KotlinSwimable, KotlinFlyable {
private val wingCount = 2
override fun move() {
println("뒤뚱뒤뚱")
}
// 추상 클래스에서 자동으로 만들어진 getter 를 오버라이드하려고 custom getter 를 쓴다
override val legCount: Int
get() = super.legCount + this.wingCount
override fun act() {
super<KotlinSwimable>.act()
super<KotlinFlyable>.act()
}
}
- 같은 이름의 default 메서드가 두 인터페이스에 있으면
super<타입>.메서드()로 어느 쪽을 부를지 고른다. - 상위 클래스의 생성자나
init블록에서open프로퍼티를 쓰면 하위 클래스가 초기화하기 전 값으로 불려 버그가 난다.
요약
- 상속하거나 구현할 때
:를 쓴다. - 상위 클래스를 상속하면 생성자를 반드시 호출한다.
override를 필수로 붙인다.- 추상 멤버가 아니면 오버라이드할 수 없다.
open을 써야 가능하다. - 상위 클래스의 생성자나
init에서open프로퍼티를 쓰면 초기화 전 값으로 불린다.
접근 제어
// 생성자에 접근 지시어를 붙이려면 constructor 를 써야 한다
open class Cat protected constructor(val name: String) {
fun hello() {
println("Hello, I'm $name")
}
}
// 유틸성 함수는 파일 최상단에 바로 적는다
fun isDirectoryPath(path: String): Boolean {
return path.startsWith("/")
}
class Car(
internal val name: String,
private val owner: String,
_price: Int
) {
var price = _price
private set // setter 에만 따로 가시성을 줄 수 있다
}
접근할 수 있는 곳은 이렇다.
public: 모든 곳. 기본값이다.protected: 선언된 클래스와 하위 클래스. Java 와 달리 같은 패키지는 빠진다.internal: 같은 모듈 안.private: 선언된 클래스 안. 파일 최상단에 쓰면 같은 파일 안.
Kotlin 은 패키지를 네임스페이스 관리용으로만 쓰고 접근 제어에는 쓰지 않는다. 그래서 protected 에서 패키지가 빠지고, Java 의 default(package-private)는 모듈 단위 접근을 통제하는 internal 로 바뀌었다. protected 는 클래스에 속하는 개념이라 파일 최상단에는 쓸 수 없다.
Java 와 함께 쓸 때 주의할 점
internal은 바이트코드에서public이 된다. Java 코드에서 Kotlin 모듈의internal코드를 가져다 쓸 수 있다.- Java 는 같은 패키지에 있는 Kotlin
protected멤버에 접근할 수 있다.
요약
- Kotlin 에서 패키지는 네임스페이스 관리용이라
protected의 의미가 달라진다. - default 가
internal로 바뀌어 모듈 사이 접근을 통제한다. - 생성자에 접근 지시어를 붙일 때는
constructor를 명시한다. - 유틸성 함수는 파일 최상단을 쓴다.
- 프로퍼티의 custom setter 에 접근 지시어를 붙일 수 있다.
- Java 에서 Kotlin 코드를 쓸 때
internal과protected를 주의한다.