본문 바로가기

Kotlin/Basic

[Kotlin] 클래스 계층 정의

인터페이스


코틀린 인터페이스 안에는 추상 메소드 뿐만이 아니라, 구현이 있는 메소드도 정의할 수 있다.

interface MyInterface{
		fun printHi()
}

class Printer: MyInterface{
		override fun printHi() = println("Hi")
}
// >> Printer().printHi()
// >> Hi

Java에서는 extends와 implements 키워드를 사용하여 상속과 구현을 처리 하지만, 코들린에서는 클래스 이름 뒤에 콜론(:)을 붙이고 인터페이스와 클래스 명을 명시하는 것으로 상속과 인터페이스 구현을 처리한다.

Override를 하는 경우, 자바는 @Override 어노테이션을 사용하는데, 코틀린에서는 그냥 Override 라는 키워드를 함수 혹은 프로퍼티 앞에 붙여준다.

또한, 인터페이스에서 이미 구현한 메소드의 경우, 디폴트 구현이 있는 것이기 때문에 아래의 코드와 같이 굳이 클래스에서 구현해 주지 않더라도 사용이 가능하다.

interface MyInterface{
		fun printHi()
		fun printBye() = println("Bye~")
}

class Printer: MyInterface{
		override fun printHi() = println("Hi~")
		// ⭐ printBye()를 구현하지 않아도 된다!
}
// >> Printer().printHi()
// >> Printer().printBye()
// >> Hi
// >> Bye

물론 새로운 로직을 정의해서 사용하는 것도 가능하다는 점!

코틀린에서의 상속(ft. open, final, abstract 변경자)


코틀린은 상속에 대해 상당히 규칙적이다.

보통 하위 클래스가 부모 클래스를 상속 받은 경우, 부모 클래스에서 변경이 일어나면 하위 클래스에 도 영향이 가는 경우가 생기기 마련이다.

즉, 어떤 클래스가 자신을 상속해야 하는지에 관한 정확한 규칙이 없다면 누군가의 수정에 의해 하위 클래스가 의도와는 다른 동작을 수행할 수 있는 위험한 상황이 생긴다.

이 문제를 해결하기 위해 코틀린에서는 하위 클래스에서 Override하게 의도된 클래스와, 메소드가 아니면 모두 기본적으로(default) final이다.

만약, 어떤 클래스나 메소드 혹은 프로퍼티의 상속을 허용하려면, 앞에 “open”이라는 키워드를 붙여줘야 한다.

예제를 통해 살펴보자.

open class Greetings : MyInterface { //⭐ 이 클래스는 open이 붙어 있기 때문에 상속이 허용되어 있다!
		
		fun welcomeGreeting() {} //⭐ 이 함수는 final로, 하위 클래스에서 오버라이드 불가능하다!
		
		open fun firstGreering() {} //⭐ 이 함수는 오버라이드 가능하다1
		
		override fun printHi() {} //⭐ 오버라이드한 함수는 기본적으로 오버라이드가 허용되어 있다.
		
		final override fun printHi() {} //⭐ 하지만 final을 명시한다면, 하위 클래스에서 오버라이드 하는 것을 막을 수 있다!
}

추상 클래스는 자바와 동일하게 abstract 키워드로 선언 가능하다.

추상 클래스는 애초에 하위 클래스에서 추상 멤버를 오버라이드 하도록 하려는 목적을 가지기 때문에, 추상 멤버(abstract가 명시된 것들) 앞에는 open키워드를 명시할 필요가 없다.

아래 코드를 보며 이해해 보자.

abstract class Animated {
    
		abstract fun animate() //⭐ 추상메소드로, 하위 클래스에서 반드시 오버라이드 해야 한다.
    
		open fun stopAnimate() {} //⭐ 추상클래스에 속하더라도, 비추상 메소드는 기본적으로 final이다.
                              // 하지만, 원하는 경우 open으로 오버라이드를 허용 할 수 있다.
}

코틀린 상속 제어 변경자 정리표를 마지막으로 글을 마무리 하겠다.

변경자오버라이드설명
final오버라이드 불가능클래스 멤버의 기본 변경자
open오버라이드 가능반드시 open을 명시해야 오버라이드 가능하다.
abstract반드시 오버라이드 해야 한다.추상 클래스의 멤버에만 붙일 수 있고, 추상 멤버에는 구현이 존재하면 안된다.
override상위 클래스나 상위 인스턴스의 멤버를 오버라이드 할 때 사용한다.오버라이드 하는 멤버는 기본적으로 허용되어 있다. 하지만, final 명시를 통해 막을 수 있다.

Uploaded by N2T