interface Clickable{
fun click()
}
class Button: Clickable{
override fun click() {
println("Button Clicked")
}
}
>>> Button().click()
Button Clicked
자바는 extends
와 implements
를 사용하지만 코틀린에서는 콜론:
으로 클래스 상속과 인터페이스 구현을 모두 처리한다. 자바와 마찬가지로 클래스는 1개만 상속 가능하고 인터페이스는 제한 없이 구현할 수 있다.
자바는 오버라이드할 때 @Override
를 생략해도 상관 없지만 코틀린은 override
메소드를 반드시 사용해야 한다.
자바 8에서는 default
키워드를 써줘야 디폴트 구현이 가능하지만 코틀린은 써줄 필요가 없다.
interface Clickable{
fun click()
fun showOff() = println("I'm clickable!")
}
// 이 인터페이스를 구현하는 클래스는 click에 대해서는 무조건 구현해야하지만
// showOff의 경우 그대로 사용 or 오버라이드할 수 있다.
default
구현이 있는 경우 인터페이스를 구현하는 하위 클래스에서 명시적으로 새로운 구현을 제공해야 한다.메소드 시그니처 : 메소드 이름 + 메소드 매개변수 리스트의 조합
interface Clickable{
fun click()
fun showOff() = println("I'm clickable")
}
interface Focusable{
fun showOff() = println("I'm focusable!")
}
class Button: Clickable, Focusable{
override fun click() {
println("Button Clicked")
}
override fun showOff() {
super<Clickable>.showOff()
super<Focusable>.showOff()
}
// 상위 타입 호출 시 super를 사용한다.
}
자바에서 코틀린의 default 메소드가 있는 인터페이스 구현하기
코틀린은 자바 6과 호환되게 설계됐다. 따라서 자바 8에서 지원하고 있는 default 메소드를 지원하지 않는다. 그래서 디폴트 메소드가 있는 인터페이스를
일반 인터페이스
+디폴트 메소드 구현이 static 메소드로 들어있는 클래스
로 조합해 구현한다. 인터페이스에는 메소드 선언만 들어간다.
그러므로 디폴트 메소드가 포함된 코틀린 인터페이스를 자바 클래스에서 구현하고 싶으면 모든 메소드에 대해 구현해야 한다.
( = 자바에서는 코틀린의 default 메소드 구현에 의존할 수 없다. )
final
로 상속을 허용하지 않고 있다. 상속을 허용하려면 open
변경자를 앞에 붙여줘야 한다.open class RichButton: Clickable{
fun disable(){} // final이므로 하위 클래스에 이 메소드 override 불가
open fun animate(){} // 하위 클래스에 이 메소드 override 가능
override fun click() {} // override한 메소드는 기본적으로 open이다.
// final override fun click()으로 다시 상속을 막을 수 있다.
}
abstract
로 추상 클래스를 선언할 수 있고 인스턴스화할 수는 없다. 추상 멤버의 경우는 하위클래스 override해야하기 때문에 항상 열려있다. 그래서 추상 멤버 앞에는 open
을 명시할 필요가 없다.abstract class Animated{
abstract fun animate() // 추상 함수이기 때문에 항상 open
open fun stopAnimatint(){...}
// 추상 함수가 아니지만 원한다면 open으로 오버라이드 허용할 수 있다.
fun animateTwice(){...}
// final이므로 override 불가
}
visibility modifer
는 코드 기반에 있는 선언에 대해 클래스 외부 접근을 제어한다.
코틀린의 기본 visiblity modifer
는 public
이다. (모두 공개)
변경자 | 클래스 멤버 | 최상위 선언 |
---|---|---|
public | 모든 곳에서 볼 수 있다. | 모든 곳에서 볼 수 있다. |
internal | 같은 모듈 안에서만 볼 수 있다. | 같은 모듈 안에서만 볼 수 있다. |
protected | 하위 클래스 안에서만 볼 수 있다. | (최상위 선언에 적용할 수 없다.) |
private | 같은 클래스 안에서만 볼 수 있다. | 같은 파일( .kt ) 안에서만 볼 수 있다. |
최상위 선언
- 파일 최상위에 선언되는 클래스, 메소드, 변수를 뜻한다.
- 자바에서는 최상위 선언에
class
만 가능하지만 코틀린에서는class
,method(fun)
,변수(val, var)
모두 가능하다.
- a.kt 파일에 아래와 같이 각각 최상위 선언을 하게되면
class
는 패키지 레벨에 최상위 선언으로 그대로 감싸진다. 그리고method
와변수
는 파일 이름에 해당하는 클래스가 만들어진 후 그 클래스 내부에 변수와 메소드로 들어가게 된다.( 자바와 호환 )// a.kt package a class Example { } val ex = 10 fun hi(){ println("hi") } // DeCompile 결과 package a; public final class Example {} public final class AKt { private static final int ex = 10; public static final int getEx() { return ex; } public static final void hi() { String var0 = "hi"; System.out.println(var0); } }
- 최상위 선언의 기본
visibility modifier
는public
이므로 전부public
으로 선언된다. 단, 변수의 경우는private
으로 선언된 다음get
메소드를public
으로 둔다.- 최상위 선언을
private
으로 선언하면 그 선언이 들어있는 파일 내부에서만 사용할 수 있기 때문에 하위 시스템의 자세한 구현 사항을 외부에 감추고 싶을 때 유용하다.
최상위 선언에서의 visibility modifier
public
: 모든 곳에서 접근 가능하다.
internal
: 같은 모듈 내부에서만 접근 가능하다. 또 접근하는 변수나 메소드는 internal
과 비교했을때 visibility
가 같거나 더 높아야한다.(internal
, private
)
모듈이란 한 번에 컴파일되는 코틀린 파일들을 의미한다.
internal open class TalkativeButton : Focusable {
private fun yell() = println("Hey!")
protected fun whisper() = println("Let's talk!")
}
fun TalkativeButton.giveSpeech(){ // 에러(public 멤버가 internal 타입인 TalkativeButton 노출)
...
}
private
클래스 멤버의 visibility modifier
public
: 모든 곳에서 접근 가능하다.
internal
: 모듈 내부에서만 접근 가능하다.
// Module1.class
class Module1 {
internal fun hi() = println("hi")
fun bye() = println("bye")
}
// Example1.kt(모듈 내부)
fun main(){
val module = Module1()
module.hi()
module.bye() // 모두 접근 가능
}
// Example2.kt(모듈 외부)
fun main(){
val module = Module1()
// module.hi() ---> internal 메소드에는 접근할 수 없다.
module.bye()
}
protected
// Person.class
open class Person {
protected fun hello() = println("Hello~")
}
// Example.kt
fun main() {
val person = Person()
// person.hello() 접근 불가능!
val student = Student()
student.hi()
// student.hello() 접근 불가능!
}
class Student : Person() {
fun hi() {
hello() // 접근 가능
}
}
private
코틀린 -> 자바로의 visibility modifier
코틀린의
public
,protected
,private
변경자는 컴파일된 자바 바이트 코드 안에서도 그대로 유지된다.
단, 최상위 선언으로private
을 선언했다면 자바에서는 클래스를private
으로 만들 수 없기 때문에private
클래스를 패키지-전용 클래스로 컴파일한다.
internal
같은 경우는 바이트 코드 상public
이 된다. 이 때 코틀린 컴파일러가internal
멤버의 이름을 나쁘게 바꾼다. 이는 모듈에 속한 클래스를 모듈 외부에서 상속할 때,
- 우연히 하위 클래스의 메소드 이름과
internal
메소드의 이름이 같아져 오버라이드하는 경우를 방지- 실수로
internal
클래스를 모듈 외부에서 사용하는걸 막기 위해서다.