Interface
선언하기
click
이라는 추상 메서드가 있는 인터페이스를 다음과 같이 작성할 수 있다.
interface Clickable{
fun click()
}
구현하기
Kotlin
에서는 :
을 통해 클래스 확장과 인터페이스 구현이 가능하다.
class Button : Clickable{
override fun click() = println("click!")
}
중요한 점은, Interface
의 경우 개수 제한 없이 구현이 가능하지만, 클래스의 확장은 오직 하나만 가능하다.
디폴트 구현
java
에서는 디폴트 메서드 선언시 default
를 작성해주어야 했지만, Kotlin
에서는 바로 작성해 주면 된다.
default
메서드는 구현을 원한다면 새로운 동작을 정의할 수 있고, 아니면 정의된 구현을 사용해도 된다.
interface Clickable{
fun click() = println("click!")
}
두 인터페이스에 같은 디폴트 메서드를 함께 구현
위에서, 한 class
에서는 interface
를 개수 제한 없이 생성할 수 있다고 했다.
그렇다면, 동일한 디폴트 메서드를 구현하는 다른 인터페이스가 존재하고 이러한 두 개의 인터페이스를 상속받은 상황에서, 디폴트 메서드를 호출했을 때 어떤 것이 호출될까?
정답은 어느쪽도 선택되지 않는다이다.
오버라이드 메서드를 직접 제공하지 않으면 컴파일 오류가 발생한다.
다음과 같이 상위 타입의 이름을 <>
사이에 넣어주고, super
를 지정하면 된다.
super<상위 타입> 메서드
Class
Open Class
Kotlin
에서는 클래스와 메서드는 기본적으로 final
이다.
상속을 허용하고 싶다면, open
변경자를 붙여야 한다.
open class RichButton : Clickable{
fun disable() {}
open fun animate() {}
override fun click() {}
}
disable
함수는 final
이다. 하위 클래스에서 오버라이드가 불가능하다.animate
함수는 open
이므로 오버라이드해도 된다.override
가 붙게 되면, 기본적으로 열려있다.
만약 override
하는 메서드의 구현을 하위에서 못하게 하려면, final
을 붙이면 된다.
protected
java
에서의 protected
는 같은 패키지 안에서 접근이 가능하다.kotlin
에서 protected
는 오직 어떤 클래스나 그 클래스를 상속한 클래스 안에서만 보인다.
sealed class
when
을 사용할 때 else
를 이용하여 아닌 경우를 처리해주어야 한다.
항상 이러한 default
분기를 추가하는 것은 번거롭다.
sealed class
를 이용해 해결이 가능하다.
상위 클래스 앞에 sealed
를 붙이면, 상속한 클래스의 정의를 제한할 수 있다.
sealed class Expr{
class Num(val value : Int) : Expr()
class Sum(val left : Expr, val right : Expr) : Expr()
}
fun eval(e :Expr) : Int =
when(e) {
is Expr.Num -> e.value
is Expr.Sum -> eval(e.right) + eval(e.left)
}
}
sealed
클래스는 when
이 모든 하위 클래스를 검사하므로, 별도의 else
가 필요없다.
sealed
는 자동으로 open
이다.
== 와 ===
java
에서 equals
와 ==
의 차이를 먼저 설명하면,equals
는 객체의 내용을 비교한다.
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2)); // true (문자열 내용이 동일)
다음과 같은 상황에서 두 객체의 내용이 모두 Hello
이기에 true
를 반환한다.
반면 ==
의 경우에는 객체의 참조 비교를 수행한다.
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2); // false (두 객체는 서로 다른 메모리 위치에 저장됨)
두 객체는 서로 다른 메모리 위치에 저장된다, 결과는 false
를 반환한다.
그렇다면 Kotlin
에서는 어떨까?
Kotlin
에서는 ==
와 ===
로 가능하다.Kotlin
에서는 반대로 ==
는 객체의 내용을 비교한다.
val str1 = "Hello"
val str2 = "Hello"
println(str1 == str2) // true (두 문자열의 내용이 동일)
다음과 같은 상황에서kotlin
은 true
를 반환한다.
만약에 객체의 참조 비교를 하고 싶다면, ===
를 사용하면 된다.
val str1 = "Hello"
val str2 = str1
println(str1 === str2) // true (str1과 str2는 같은 문자열 객체를 가리킴)
만약에 클래스를 ==
로 비교한다고 한다면, equals()
를 오버라이드하여 원하는 동등성을 비교해야한다.
equals
의 인자는 Any
이다. Any
는 모든 클래스의 상위 클래스이다.
fun equals(other: Any?): Boolean
Object
객체 선언
object decoration
은 싱글턴을 정의하는 방법이다.
동반 객체
companion object
는 인스턴스 메서드는 아니지만 어떤 클래스와 관련 있는 메서드와 팩토리 메서드를 담을 때 쓰인다.
객체 선언 : 싱글턴을 쉽게 만들기
Kotlin
에서는 객체 선언기능 (object)
를 통해 싱글턴을 언어에서 기본 지원한다.객체 선언
은 클래스 선언과 클래스에 속한 단일 인스턴스
의 선언을 합친 선언이다.
싱글턴 객체는 생성자
가 필요가 없다.
객체 선언문이 있는 위치에서 생성자
호출 없이 만들어진다.
Object의 상속
object
도 클래스나 인터페이스 상속이 가능하다.
동반 객체 : 팩토리 메서드와 정적 멤버가 들어갈 장소
코틀린 언어는 static
키워드를 지원하지 않는다.
대신에 최상위 함수를 활용하는 편을 권장한다.
하지만, 최상위 함수의 경우 private
클래스의 비공개 함수를 접근할 수 없다.
그렇기에, 클래스 내부 정보에 접근해야 하는 함수가 필요할 때는 클래스에 중첩된 객체 선언의 멤버 함수로 정의해야 한다.
'안드로이드 > Action Kotlin' 카테고리의 다른 글
Action Kotlin 6 - 연산자 오버로딩과 기타 관계 (0) | 2023.10.30 |
---|---|
Action Kotlin 5 - 코틀린 타입 시스템 (0) | 2023.10.27 |
Action Kotlin 4 - 람다로 프로그래밍 (0) | 2023.10.25 |
Action Kotlin 2 - 함수의 정의와 호출 (0) | 2023.10.24 |
Action Kotlin - 1 (0) | 2023.10.24 |