Kotlin 기본 클래스
Kotlin의 기본 클래스를 정리해 보겠습니다
생성자
// constructor 생략가능
constructor를 생략하여 간단하게 class ClassName(name:String)
초기화
init 블럭을 사용하는방법과 사용하지않고 바로 변수에 저장하는 방법이 있습니다.
1개 이상의 생성자
consturctor을 여러 개로 정의할 수 있는데 위와같은 형태로 constructor를 이용해 생성자 오버로딩을 할 수있습니다.
첫번째 생성바 val name:String
두번째 생성자 name:String, age:Int :this(name){ }
name은 중복적으로 사용되는 키워드이므로 기존 생성자로 넘겨주기 위해서 this() 키워드를 사용하여 정의 가능 합니다.
생성자 private로 사용하기
java 에서는 싱글톤을 사용하는 경우 private를 정의하여 생성자를 가립니다.
Kotlin에서도 private의 생성자를 만들수 있는데 다음과 같습니다.
Kotlin 상속
class UseBase(age: Int) : Base(age)
Kotlin에서는 abstract와 interface에 대한 별도 구분 없이 : 으로 구분합니다.
Android 에서 많이 사용하는 View상속은 아래와같이 처리할 수 있습니다.
함수 Overriding
함수를 Overriding을 하기 위해서 java에서는 abstract 또는 interface를 사용합니다
abstract는 extends을 이용하여 상속을 구현하고,interface은 implements을 이용하여 상속을 구현합니다.
Koltin에서는 Interface와 Abstract를 : 로 처리합니다.
open 이라는 키워드를 함께 사용하면 아래와 같습니다.
Kotlin open
Kotlin에서 사용하게 되는 open 키워드는 다음과 같습니다.
- java에서는 상속의 재 정의를 방지하기 위해 final을 사용합니다.
- Kotlin에서는 반대로 상속의 재정의를 허용하기 위해 open을 사용합니다.
open은 변수에서도 사용이 가능한데 아래와 같습니다.
Overriding Rules
아래의 코드에서 다중 상속을 허용하게 됩니다.
해당 c() 의 f() 함수를 실행한 결과는 아래와 같습니다.
•print(“A”), print(“B”)
open의 클래스A의 f() 함수와 B interface의 f() 함수가 다중으로 상속되는 상황입니다.
그래서 super<Base>의 형태로 함수를 각각 불러올 수 있습니다.
class C()에서 보듯 f() 함수를 정의한 부분을 살펴볼 수 있습니다.
super<A>.f()
는 A.f()를 하는 것과 동일합니다.super<B>.f()
는 B.f()를 하는 것과 동일합니다.함수 f()
가 open class A
의 f()
도 상속받았고, interface B
의 f()
도 함께 상속이 된 상태라서 가능한 rule입니다.
추가로 Java 8 이전 버전을 공부하신 분은 interface
에서 함수 정의
가 가능함을 의아해하실 수 있을 것 같습니다. 다음의 java 8 virtual extension methods
자료를 참고하시면 되겠습니다.
추가로 Kotlin의 open class를 추가하여 아래와 같이 확장도 가능합니다.
}
open 클래스의 f() 함수는 override가 가능한 형태입니다.
이를 AbstractBase에서 상속받고, abstract로 확장할 수 있습니다.
Kotlin의 static - companion object
val className = ClassName().getInstance()
Sealed Classes
열거 형태로 자기 자신을 return이 가능하고 , 다음과 같이 class와 object에 자기 자신을 return하는 클래스 형태를 제공합니다.
대략 다음을 실행하면 eval 이라는 함수에 Expr을 셋팅합니다. when으로 동작하는데 Expr의 Sum 클래스를 초기화 합니다.
초기화 시에는 2개의 Exptr을 사용하고, 이를 +하는 함수입니다. 실제로는 expr.number을 가져와서 처리하는 예제입니다.
ex) sealed와 중첩 클래스 : 모든 경우의 수에 대해 분기 처리하도록 강제, 실수 방지
when
에는 반드시 else
(디폴트 분기)를 적어주어야 한다.Expr
클래스 계층에 새로운 하위 클래스를 추가했을 때, when
에 추가하는 것을 깜빡해도 디폴트 분기를 타게 되므로 프로그램이 예상대로 동작하는 것 처럼 보여 이를 잡아내기가 어려워질 수 있다. interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
fun eval(e: Expr): Int =
when (e) {
is Num -> e.value
is Sum -> eval(e.right) + eval(e.left)
else -> throw IllegalArgumentException("Unknown expresssion")
}
sealed
와 중첩 클래스를 사용하면 디폴트 분기를 사용하지 않고 모든 경우의 수를 처리하도록 강제할 수 있어 더 확실하게 검사할 수 있다.sealed
class는 자동으로 open
이다.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)
}
'Kotlin' 카테고리의 다른 글
Kotlin List, Map (4) | 2019.01.23 |
---|---|
Kotlin enum과 when (4) | 2019.01.23 |
Kotlin - Realm 사용하기 (2) | 2019.01.07 |
Kotlin - 소리 재생하기(MediaPlayer ,SoundPool 클래스, 버전분기) (2) | 2019.01.05 |
Kotlin - 체인모드(ContraintLayout) (2) | 2019.01.05 |
댓글