[Kotlin] Kotlin Study #6

이제일·2023년 8월 27일
0

Kotlin

목록 보기
5/10

Class Relationships

관계 종류

  • 상속관계 is-a : 상위 클래스의 전부를 가져와 하나의 클래스 처럼 사용
  • 연관관계 has-a : 내부적인 속성에서 객체를 만들어 사용
    • 결합관계 약한 has-a : 클래스 간 주종관계 없이 단순하게 사용
    • 조합관계 강한 has-a : 클래스 간의 주종관계가 있어 따로 분리해서 사용할 수 없는 관계
    • 의존관계 사용 has-a : 필요 클래스를 매개변수 등으로 받아 필요한 시점에 사용

결합(Aggregation)관계

  • 약한 has-a
  • 단순하게 사용될 클래스의 객체를 속성으로 만들어 사용함.
  • 클래스끼리는 동일한 생명주기일 필요 없음.

시나리오 - 학생, 대학교, 주소의 3가지 클래스

class Address(
    val country: String,
    val city: String

class College(
    val collegeName: String,
    val collegeAddress: Address
)
class Student(
    val studentName: String,
    val studentAddress: Address,
    val studentCollege: College
)

조합(Composition)관계

  • 결합관계보다 더 결합이 강한 관계
  • 두 클래스는 주종 관계이며, 생명주기도 동일

시나리오 - 자동차, 엔진, 생성의 3가지 클래스, 자동차 생성시 엔진 생성을 강제

class CarProduct(color: String, maxSpeed: Int): Car(color, maxSpeed){
	lateinit var carEngine: CarEngine
	fun setCar(){
    	carEngine = CarEngine()
        carEngine.startEngine()
    }
}

open class Car(val color: String, val maxSpeed: Int) {
    fun carInfo() { println("$color $maxSpeed $name") }
}

class CarEngine {
    fun startEngine() { println("엔진 가동") }
    fun stopEngine() { println("엔진 중단") }
}

의존(Dependency)관계

  • 명확한 관계 없이 특정 시점에 객체를 전달받아 사용
  • API 활용 시 대부분은 기능만 가져다 사용하기에 해당 관계로 구성

시나리오 - 계좌, 고객 2가지 클래스로 고객이 계좌의 기능을 사용하는 관점

class Account(val accountNo: Int, var balance: Int=0) {
	fun deposit(amount: Int){
		balance += amount
    }
}

class Customer(var balance: Int) {
	fun makedeposit(acc: Account){
    	acc.deposit(balance)
    }
}

속성과 메서드 Override

getter, setter

  • 변수를 생성하면 내부적으로 게터와 세터가 생성된다
class Person {
    val gender: String
        get() = "male$age"

    var age: Int = 3
        get() {
            return field + 1
        }
        private set(value) {
            field = value + 1
        }
}

연산자 오버로딩

  • operator 예약어를 사용해서 연산자에 해당하는 메서드를 재정의 할 수 있음.
data class Price(val value: Int) {
    operator fun plus(b: Price): Price {
        return Price(value + b.value)
    }
}

테이블 참고

infix 처리 (중위 표현법)

  • 이항연산자를 추가하는 것처럼 보이는 함수
    • 멤버 메서드 또는 확장 함수여야 함.
    • 하나의 매개변수를 가져야 함.
    • infix 키워드를 사용하여 정의해야 함.
infix fun Int.add(x:Int):Int{
    return this + x
}

println(3.add(5)) // 8
println(3 add 5) // 8

특수 목적 클래스

Data Class

class 앞에 data 를 붙여 데이터 보관 목적으로 클래스를 생성할 수 있다.

data class User(val name: String, val age: Int)

특징은 다음과 같다

  • 주 생성자(primary constructor)는 1개 이상의 프로퍼티를 선언되어야 한다.
  • 생성자 프로퍼티는 val 또는 var으로 선언해야 한다.
  • 데이터 클래스에 abstract open sealed inner 를 붙일 수 없다.
  • 데이터 클래스는 상속받을 수 없다.
  • equals() hashCode() toString() componentN() copy()를 자동으로 구성해준다.
    해당 메서드들은 주 생성자에 의존한다

Data Class가 상속이 안되는 이유로는 equals()를 제대로 정의할 수 없기 때문이다

Enum Class

  • 여러 상수값을 그룹화하고, 각 상수 값이 해당 그룹의 모든 값 중 하나임을 보장
class Task {
    var state: State = State.WAITING

    fun printState() =
        when(state){
            State.WAITING -> println("Waiting..")
            State.PROCESSING -> println("Processing..")
            State.DONE -> println("Task done")
        }

    enum class State {
        WAITING, PROCESSING, DONE
    }
}
  • 각각의 enum 은 enum class 의 인스턴스 이므로 특정 값으로 초기화 될 수 있으며, 메서드를 가질 수 있다
  • 메서드 선언 이전에 ;로 속성의 선언이 끝났음을 명시해야한다
enum class Color(val r: Int, val g: Int, val b: Int) {
    RED(255, 0, 0), GREEN(0, 255, 0), BLUE(0, 0, 255), 
    WHITE(255, 255, 255), BLACK(0, 0, 0), YELLOW(255, 255, 0);

    fun rgb(): String =
    	"0x"+String.format("%02x", r)+String.format("%02x", g)+String.format("%02x", b)
}
fun main(){
    println(Color.RED.rgb()) // 0xff0000
}
profile
세상 제일 이제일

0개의 댓글