개발 이론/Kotlin

[Kotlin] 기초 개념 (2)

dal_been 2024. 4. 20. 22:16
728x90

이전 블로그에서 헷갈리는 기초개념을 정리했다.

이번 블로그에서도 헷갈리는 기초개념을 정리할 예정이다.

 


인터페이스

 

자바의 경우 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 뭔가 익숙하지 않으니까.. 어렵..당...ㅎㅎ