open class Shape {
open fun draw() { /*...*/ }
fun fill() { /*...*/ }
}
class Circle : Shape() {
override fun draw() { /*...*/ }
}
Circle.draw()에는 override 가 필요 ⇒ 이 수정자가 없으면 컴파일러가 오류를 발생
함수에 open 이 없으면, 서브클래스에서 동일한 시그니처의 메서드를 선언할 수 없다.
open 수정자는 final 클래스(즉, open 수정자가 없는 클래스)의 멤버에 추가해도 효과가 없다.
재오버라이드 금지
override로 표시된 멤버는 기본적으로 open이므로 서브클래스에서 다시 오버라이드할 수 있다. 재오버라이드를 금지하려면 final을 사용해야 한다.
open class Rectangle : Shape() {
final override fun draw() { /*...*/ } // 재오버라이드 금지
}
💗 속성 오버라이딩 Overriding properties
오버라이딩 메커니즘은 메서드뿐만 아니라 속성에도 동일하게 적용.
슈퍼클래스에서 선언된 속성을 파생 클래스에서 다시 선언하려면 override로 시작해야 하며, 호환 가능한 타입을 가져야 한다.
각 선언된 속성은 초기값을 가진 속성이나 get 메서드를 가진 속성으로 오버라이드할 수 있다.
open class Shape {
open val vertexCount: Int = 0
}
class Rectangle : Shape() {
override val vertexCount = 4
}
💫 val 속성을 var 속성으로 오버라이드 가능 (반대는 불가능)
val 속성을 var 속성으로 오버라이드할 수 있지만, 그 반대는 불가능하다.
이는 val 속성이 기본적으로 get 메서드를 선언하고, 이를 var로 오버라이드하면 get 메서드와 함께 set 메서드를 추가로 선언하기 때문이다.
기본 생성자에서 속성 선언의 일부로 override 키워드를 사용할 수도 있다.
interface Shape {
val vertexCount: Int
}
class Rectangle(override val vertexCount: Int = 4) : Shape // 항상 4개의 꼭짓점을 가짐
class Polygon : Shape {
override var vertexCount: Int = 0 // 나중에 어떤 숫자로든 설정할 수 있음
}