[Kotlin] 기초 개념 (2)
이전 블로그에서 헷갈리는 기초개념을 정리했다.
이번 블로그에서도 헷갈리는 기초개념을 정리할 예정이다.
인터페이스
자바의 경우 implements, extends를 사용하여 구현과 상속을 했다. Kotlin에서는 공통적으로 ":"을 사용한다.
인터페이스 메서드 구현은 override 변경자를 반드시 붙여야함
interface Click {
fun click()
}
class Button: Click {
override fun click() {
prinln("click Button")
}
}
open, final, abstract 변경자 : 기본 final
Kotlin은 기본적으로 모든 클래스, 메서드 final class 임으로 open class, method인 경우 상속가능
open class CustomButton: Click {
//final method라서 오버라이드 불가
fun stop() {}
//open method 오버라이드 가능
open fun custom() {}
//오버라이드 메서드 오버라이드 가능
override fun click {}
}
Sealed class
확장을 제한하여 편의성을 향상시키는 클래스 타입
인터 페이스를 활용하여 when절을 할때 불필요한 else문이 필요하다
- 컴파일러 입장에서는 Error interface를 구현한게 무엇인지 할 수 없기 때문에
- 만약 Error interface를 구현한 클래스가 추가될때 해당 클래스를 추가해야하는데 누락할 위험이 존재
interface Error
class ClientError(val message: String): Error
class DataError(val dbType: DbType): Error
enum class DbType {
MySQL, H2, MARIADB
}
fun getError(error: Error) = when (error) {
is ClientError -> "Error is ${error.message}"
is DataError -> "Error is ${error.DbType}"
else -> throw IllegalArgumentException("Unknown")
}
그래서 Sealed 클래스를 활용하면
when절에 불필요한 else문 제거 가능하고 신규 구현체를 만들때 자동으로 컴파일 에러 발생하여 수정이 쉬워진다
sealed class Error {
class ClientError(val message: String): Error
class DataError(val dbType: DbType): Error
}
enum class DbType {
MySQL, H2, MARIADB
}
fun getError(error: Error) = when (error) {
is Error.ClientError -> "client Error"
is Error.DataError -> "data Error"
}
상속
기본적인 상속 구조는 Child1을 보면 된다.
만약 기본생성자말고 부가적인 생성자가 필요하다면 Child2와 같이 생성가능하다
open class Parent(
val parentName: String
)
class Child1(
val childName: String,
parentName: String
): Parent(parentName)
class Child2: Parent{
private val childName: String
constructor(childName: String): this(childName,"")
constructor(childName: String, parentName:String): super(parentName) {
this.childName = childName
}
}
Backing field
프로퍼티의 getter/setter 커스터마이징 가능
class Account {
var amount: Long = 0
set(value) {
if(value < 0) throw IllegalStateException("잔액은 0월이상")
field = value
}
var name: String = ""
get() = "계좌이름: $field"
}
접근자 가시성
private set을 통해 setter만을 감춤
class Account {
var amount: Long = 0
private set
}
data class
toString(), equals(), hashCode()를 제공해준다
data class Member(val name: String, val age: Int)
object 키워드
자바의 싱글톤과 같은 목적으로 클래스 선언과 객체 생성을 동시에 진행
직접생성할 필요가 없으며 별도의 인스턴스 생성 불가
object Team {
val members = mutableListOf<Member>()
}
자바의 static method 대체 용도
class Member {
private val name: String
private val age: Int
compaion object {
fun name(
name: String
): Member = Member(name,0)
fun age(
age: Int
): Member = Member("default", age)
}
}
컬렉션
수정불가능한 컬렉션과 수정가능한 컬렉션이 존재한다.
수정 불가능한 컬렉션
- get, size, iterator, contains등 읽기 기능만 제공
- 생성 방법 : listOf(), mapOf(), setOf()
수정 가능한 컬렉션 : MutableCollection
- add, remove, clear등의 추가, 삭제, 수정 기능 제공
- 생성 방법 : mutableListOf(), mutableMapOf(), mutableSetOf()
범위함수
특정 범위(객체 컨텍스트) 내에서 코드 블록을 실행하는 여러함수
-> 특정한 객체를 영역을 한정하여 활용하고 싶은 경우
class Person(
var name: String,
var age: Int
) {
fun isChild(): Boolean = age < 15
}
fun main() {
val person = Person("hello", 17)
val isChild = person.run{
age = 10
isChild()
}
println("아이입니까? $child")
}
일단 기초 개념 마무리... 이제는 실습프로젝트로...
아니 kotlin 뭔가 익숙하지 않으니까.. 어렵..당...ㅎㅎ