인터페이스
interface Remote { fun up() fun down() fun doubleUp() { up() up() } companion object { // 두 개의 리모컨을 묶어서 한번에 두 개의 리모컨에 동시에 명령을 내릴 수 있는 combine() 메서드 fun combine(first: Remote, second: Remote): Remote = object: Remote { override fun up() { first.up() second.up() } override fun down() { first.down() second.down() } } } } class TV { var volume = 0 } class TVRemote(val tv: TV) : Remote { override fun up() { tv.volume ++ } override fun down() { tv.volume -- } }
추상 클래스
abstract class Musician(val name: String, val activeFrom: Int) { abstract fun instrumentType(): String } // Cellist의 생성자의 파라미터를 Musician에게 파라미터 넘겨서 생성 class Cellist(name: String, activeFrom: Int): Muisician(name, activeFrom) { override fun instrumentType() = "String" } val ma = Cellist("Yo-Yo Ma", 1961)
중첩 클래스와 내부 클래스
class TV { private var volume = 0 val remote: Remote get() = TVRemote() override fun toString(): String = "Volume: $volume" inner class TVRemote: Remote { override fun up() { volume++ } override fun down() { volume-- } override fun toString() = "Remote: ${this@TV.toString()}" // this@TV 는 TVRemote의 this가 아닌 TV에서의 this임 } }
- inner 를 통해 내부 클래스를 만들면, TVRemote 클래스에서 TV 클래스의 private 변수(
volume
)에 접근이 가능함 - 코틀린의 중첩 클래스는 Java 와는 다르게 외부 클래스의 private 멤버에 접근이 불가능 함
상속
[Kotlin docs ] Inheritance
- 인터페이스와는 다르게 코틀린의 클래스는 디폴트가 final 임 → 클래스로부터 상속 받을 수 없음
- open 이라고 명시되어 있는 클래스로부터만 상속을 받을 수 있음
- 속성도 오버라이드 할 수 있다
- val 로 정의된 속성은 오버라이드 할 때 val, var 모두를 사용해서 오버라이드 가능
- var 로 정의된 속성은 var 로만 오버라이드 가능
- 왜냐면 val은 getter만 갖고 있고, 자식 클래스에서 var로 오버라이드 하며 setter 를 생성할 수 있지만, var 로 생성한 속성을 val로 오버라이딩 하면서 setter를 제거할 수 없기에.
- Java와는 다르게 코틀린은
implements
와extends
를 구분하지 않음
Sealed 클래스
- 코틀린의 한쪽 극단엔 final이 존재. open으로 표기되어 있지 않아 자식클래스가 하나도 없는 클래스
- 반대 극단엔 open과 abstract 클래스가 있음. open과 abstract 는 어떤 클래스가 상속을 받았는지 전혀 알 수 없음.
- 클래스를 만들 때 작성자가 지정한 몇몇 클래스에만 상속할 수 있도록 하는 중간영역이 있다면…
Sealed
클래스는 동일한 파일에 작성된 다른 클래스들에 확장이 허용되지만 그 외의 클래스들은 확장할 수 없는 클래스이다.sealed class Card(val suit:String) class Ace(suit: String) : Card(suit) class King(suit: String) : Card(suit) { override fun toString() = "King of $suit" }
- sealed 클래스의 생성자는 private이 표시되지 않았지만 private으로 취급됨