Languages

kotlin in Action 4장 예제 (by, selaed, factory method, constructor)

!쪼렙조햄 2020. 4. 26. 21:25
반응형

by 예제

interface Attackable {
    fun attack(): String
}

class Knife : Attackable {
    override fun attack() = "attack with knife"
}

class Gun : Attackable {
    override fun attack() = "attack with gun"
}

class Attacker(val impl: Attackable) : Attackable by impl {
    fun attackEmoji() = "${attack()} 😱😵"
}

fun main() {
    println(Attacker(Knife()).attackEmoji())
    println(Attacker(Gun()).attackEmoji())
}

  • 하위 클래스가 상위 클래스를 상속해서 상위 클래스 메소드를 오버라이드 하는 경우
    • 상위 클래스 변경이 되면 문제가 생긴다
    • 그래서 코틀린의 기본적인 클래스는 final
    • 상속 불가능한 클래스를 그대로 사용하면서 새로운 기능을 추가할때 by 사용 (위임 기능)
  • by 사용으로 클래스 간의 결합도를 낮출 수 있다
  • 예제
    • final class 이고 Attackable을 상속하는 Knife, Gun class 존재
    • Attackable class를 위임하는 Attacker 클래스를 만들어서 emoji를 함께 리턴하는 attackEmoji 함수를 추가하는 예제

factory method

interface Weapon {
    fun attack()
}

class Knife : Weapon {
    override fun attack() = println("attack with knife")
}

class Gun : Weapon {
    override fun attack() = println("attack with gun")
}

fun WeaponFactory(type: String): Weapon {
    when (type) {
        "knife" -> return Knife()
        "gun" -> return Gun()
        else -> return Knife()
    }
}

fun Attack(weapon: Weapon) = weapon.attack()

fun main() {

    var type = "gun"

    // 기존 코드
    when (type) {
        "knife" -> Attack(Knife())
        "gun" -> Attack(Gun())
    }

    // factory method 적용 코드
    Attack(WeaponFactory(type))
}
  • 객체 인스턴스를 생성하는 부분을 별도의 인터페이스로 분리
  • 이 분리된 인스턴스가 공장처럼 생성자로 객체를 만들어낸다고 해서 팩토리 메소드

kotlin의 객체 동등성

fun main(){ 

val gun1 : String = "gun"
val gun2 : String? = "gun"
println(gun1 == gun2) // true
println(gun1 === gun2) // true
} 

selaed 클래스

sealed class Weapon { 

fun attack() = "attack"
} 

class Knife : Weapon() 
class Gun : Weapon() 

fun Attack(weapon: Weapon) { 
when (weapon) { 
is Knife -> println("${weapon.attack()} with knife") 
is Gun -> println("${weapon.attack()} with gun") 
} 
} 

fun main() = Attack(Knife()) 

주생성자와 부 생성자 같이 쓰기

class Weapon (var type : String){ 

constructor(_type:String, _emoji:String):this(_type){ 
// 주 생성자 호출 없으면 Primary constructor call expected 오류 발생
type = _type+_emoji 
} 
} 

fun main(){ 
val weapon1 = Weapon("gun") 
val weapon2 = Weapon("gun", "\uD83D\uDE31\uD83D\uDE35") 
println(weapon1.type) 
println(weapon2.type) 
} 
반응형