코틀린 인터페이스

코틀린 인터페이스(Interface) 완벽 정리

인터페이스는 클래스의 청사진(규약) 역할을 한다.
즉, 어떤 기능을 반드시 구현하도록 강제하면서도,
여러 클래스에 공통된 기능을 부여할 수 있다.


기본 문법

interface Clickable {
fun click()
}
class Button : Clickable {
override fun click() {
println("버튼 클릭됨")
}
}

인터페이스는 다중 구현 가능

코틀린 클래스는 다중 상속이 불가능하지만,
여러 인터페이스를 동시에 구현할 수 있다.

interface Clickable {
fun click()
}
interface Focusable {
fun focus()
}

class UIComponent : Clickable, Focusable {
override fun click() = println(“클릭 이벤트 처리”)
override fun focus() = println(“포커스 이벤트 처리”)
}


기본 구현이 있는 함수

인터페이스의 함수는 기본 구현(body) 을 가질 수 있다.

interface Clickable {
fun click()
fun showStatus() = println("클릭 가능한 객체입니다.")
}
class Button : Clickable {
override fun click() = println(“버튼 클릭됨”)
}

val btn = Button()
btn.click()
btn.showStatus()

인터페이스 다중 상속 시 충돌 해결

여러 인터페이스에서 같은 이름의 메서드를 구현하면,
명시적으로 어느 인터페이스의 메서드를 사용할지 지정해야 한다.

interface A {
fun show() = println("A의 show()")
}
interface B {
fun show() = println(“B의 show()”)
}

class C : A, B {
override fun show() {
super<A>.show()
super<B>.show()
println(“C의 show()”)
}
}

val c = C()
// 출력:
// A의 show()
// B의 show()
// C의 show()

인터페이스 속성(Property)

인터페이스에서도 속성을 선언할 수 있지만,
초기값은 가질 수 없다. (구현 클래스에서 반드시 정의해야 함)

interface User {
val name: String
}
class Member(override val name: String) : User


인터페이스 상속

인터페이스끼리도 상속이 가능하다.

interface Drawable {
fun draw()
}
interface Resizable : Drawable {
fun resize()
}

class Image : Resizable {
override fun draw() = println(“이미지 그림”)
override fun resize() = println(“이미지 크기 조정”)
}


추상 클래스 vs 인터페이스

구분 추상 클래스 인터페이스
인스턴스 생성 불가능 불가능
목적 공통 로직 제공 + 상태 유지 동작 규약 정의
생성자 있음 없음
속성 상태(값) 유지 가능 상태 유지 불가 (get만 가능)
다중 상속 불가 가능
사용 예 기본 기능 + 확장성 규칙 정의, 이벤트 리스너 등

인터페이스 안의 default, abstract 차이

모든 함수는 기본적으로 abstract 이지만,
구현부가 있으면 자동으로 default 역할을 한다.

interface Animal {
fun eat() // abstract
fun breathe() = println("숨쉬기") // default
}

인터페이스 안의 companion object

인터페이스도 companion object를 가질 수 있다.
이를 통해 상수나 팩토리 메서드를 정의할 수 있다.

interface Configurable {
companion object {
const val VERSION = "1.0.0"
fun info() = println("설정 인터페이스 버전: $VERSION")
}
}
Configurable.info()


인터페이스 활용 예시

1. 클릭 리스너

interface OnClickListener {
fun onClick()
}
class Button(private val listener: OnClickListener) {
fun click() = listener.onClick()
}

val button = Button(object : OnClickListener {
override fun onClick() {
println(“버튼이 클릭되었습니다.”)
}
})

button.click()

2. Repository 패턴

interface Repository {
fun findAll(): List<String>
}
class UserRepository : Repository {
override fun findAll(): List<String> {
return listOf(“재은”, “철수”, “민수”)
}
}


  • 공통된 동작 규약 정의용으로 인터페이스를 우선 고려

  • 여러 클래스에 동일한 기능을 부여해야 한다면 인터페이스가 적합

  • 기본 구현이 가능하므로, 불필요한 중복 코드를 줄일 수 있다

  • 충돌 시 super<인터페이스명>.함수()로 명시적으로 해결


게시됨

카테고리

작성자

댓글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다