본문 바로가기
Kotlin

[Kotlin] open class와 abstract class

by 태크민 2024. 11. 2.

코틀린에서의 final

자바에서는 final 로 명시적으로 상속을 금지하지 않는 모든 클래스를 다른 클래스가 상속할 수 있다. 이렇게 기본적으로 상속이 가능하면 편리한 경우도 많지만 문제가 생기는 경우도 많다.

취약한 기반 클래스(fragile base class)
하위 클래스가 기반 클래스에 대해 가졌던 가정이 기반 클래스를 변경함으로써 깨져버린 경우에 생긴다.
어떤 클래스가 자신을 상속하는 방법에 대해 정확한 규칙을 제공하지 않는다면 그 클래스의 클라이언트는 기반 클래스를 작성한 사람의 의도와 다른 방식으로 메서드를 오버라이드할 위험이 있다.
모든 하위 클래스를 분석하는 것은 불가능 하므로 기반 클래스를 변경하는 경우 하위 클래스의 동작이 예키지않게 바뀔 수도 있다는 면에서 기반 클래스는 취약하다.

"상속을 위한 설계와 문서를 갖추거나, 그럴 수 없다면 상속을 금지하라."
이는 하위클래스에서 오버라이드하게 의도된 클래스와 메서드가 아니라면 모두 final로 만들라는 뜻이다.

코틀린도 마찬가지다.
자바의 클래스와 메서드는 기본적으로 상속에 열려있지만 코틀린의 클래스와 메서드는 기본적으로 final이다.
어떤 클래스의 상속을 허용하려면 클래스 앞에 open 변경자를 붙여야한다.
오버라이드를 허용하고 싶은 메서드나 프로퍼티의 앞에도 open 변경자를 붙여야한다.

 

Clickable.kt
package chapter4_클래스_객체_인터페이스._2_변경자._open

interface Clickable {
    fun click()
    fun showOff() = println("I'm clicked") // default 구현이 있는 메서드
}

 

RickButton.kt
package chapter4_클래스_객체_인터페이스._2_변경자._open

open class RichButton : Clickable { // 이 클래스는 열려있다. 다른 클래스가 이 클래스를 상속할 수 있다.
    fun disable() {}  // default final 이다. 하위 클래스가 이 메서드를 오버라이드 할 수 없다.
    open fun animate() {} // 하위클래스가 이 메서드를 오버라이드 할 수 있다.
    final override fun click() {} // 이 함수는 상위 클래스의 열려있는 메서드를 오버라이드한다. 오버라이드한 메서드는 기본적으로 열려있다.
}

 

1) open class 클래스명

open class RichButton : Clickable {

이 클래스는 다른 클래스가 상속할 수 있다.

 

2) 아무것도 선언되어있지 않은 default 는 final 이다.

fun disable() {}

 

3) open fun 메서드명

open fun animate() {}

하위 클래스가 이 메서드를 오버라이드 할 수 있다.

 

4) final override fun 메서드명

final override fun click() {}

final 이 없는 override 메서드나 프로퍼티는 기본적으로 열려있다. 따라서 오버라이드 하지못하게 금지하려면 오버라이드하는 메서드 앞에 final을 명시해야한다.

 

 

abstract

추상클래스를 생성한다.

 

Anumated.kt
abstract class Animated { // 추상클래스다. 이 클래스의 인스턴스를 만들 수 있다.
    abstract fun animated() // 이 함수는 추상 함수다. 이 함수에는 구현이 없다. 하위 클래스에서는 반드시 오버라이드해야한다.
    // 추상클래스에 속했더라도 비추상함수는 기본적으로 파이널이지만 원한다면 open 으로 오버라이드 허용할 수 있다.
    open fun stopAnimating() {}
    fun animateTwice() {}
}

 

1) abstract class 클래스명

추상클래스다.

 

2) abstract fun 메서드명

추상 함수다. 이 함수에는 구현이 없으며, 하위 클래스에서는 반드시 오버라이드 해야하는 메서드다.

 

3) oepn fun 메서드명

추상클래스에 속했더라도, 비추상함수는 기본적으로 final 이다. 하지만 원한다면 open 을 사용하여 오버라이드를 허용할 수 있다.

 

인터페이스 멤버의 경우
인터페이스 멤버의 경우 final, open, abstract 를 사용하지 않는다.인터페이스 멤버는 항상 열려있으며 final 로 변경할 수 없다.인터페이스 멤버에게 본문이 없으면 자동으로 추상 멤버가 되지만, 그렇더라도 따로 멤버 선언 앞에 abstract 키워드를 덧붙일 필요가 없다.

 

클래스 내의 상속 제어 변경자 의미

변경자 이 변경자가 붙은 멤버는 설명
final 오버라이드 불가능 클래스 멤버의 기본 변경자다.
open 오버라이드 가능 반드시 open을 명시해야 오버라이드 가능하다.
abstract 반드시 오버라이드 필수 추상 클래스의 멤버에만 이 변경자를 붙일 수 있다.
추상 멤버에는 구현이 있으면 안된다.
override 상위 클래스나 상위 인스턴스의 멤버를 오버라이드하는 중 오버라이드하는 멤버는 기본적으로 open이다.
하위 클래스의 오버라이드를 금지하려면 final을 명시해야한다.

 


참고자료

https://devfunny.tistory.com/756

 

[Kotlin in Action] 14. 코틀린의 가시성 변경자 (open, abstract, internal)

코틀린에서의 final 자바에서는 final 로 명시적으로 상속을 금지하지 않는 모든 클래스를 다른 클래스가 상속할 수 있다. 이렇게 기본적으로 상속이 가능하면 편리한 경우도 많지만 문제가 생기

devfunny.tistory.com

https://jslee-tech.tistory.com/49

 

(Kotlin) open class, abstract class

Java에는 final이라는 키워드가 있다. final로 선언된 클래스와 메소드는 기본적으로 상속과 오버로드가 제한된다. 즉, 자식 클래스에서 이 클래스나 메소드를 재정의하려 할 때 컴파일 에러를 발생

jslee-tech.tistory.com

 

'Kotlin' 카테고리의 다른 글

[Kotlin] 컬렉션(Collection) 함수  (9) 2024.11.04
[Kotlin] by란?  (0) 2024.11.02
[Kotlin] 깊은 복사 (Deep Copy) 3가지 방법  (0) 2024.11.02
[Kotlin] Object 키워드 (with companion object)  (0) 2024.11.02
[Kotlin] Data Class란?  (3) 2024.11.02