[코틀린] study day 8

승아·2020년 10월 27일
0

추상 클래스(abstract class)

  • open 키워드를 사용하지 않고도 파생 클래스 작성 가능
abstract class Animal(val name: String, val color: String, val weight: Double){
	// 추상 프로퍼티 ( 반드시 하위 클래스에서 재정의해 초기화해야 함)
	abstract var dog: String
    
    // 일반 프로퍼티 (초기 값인 상태를 저장할 수 있음)
    var cat = "cat"
    
    // 추상 메서드 (반드시 하위 클래스에서 구현해야 함)
    abstract fun feed()
    abstract fun play()
    
    // 일반 메서드
    fun walk(){
    	println("walk")
    }
}

class Dog(name: String, color: String, weight: Double, override vardog: String): Animal(name, color, weight) {
    override fun feed(){
        println("dog feed")
    }
    override fun play(){
        println("dog play")
    }
}
  • object를 사용한 생성
abstract class Speaker {
    abstract fun listen() // 추상 메서드
}

val mySpeaker = object: Speaker() { // 객체 인스턴스
    override fun listen() { // 추상 메서드의 구현
        println("출력합니다.")
    }
}

fun main() {
    mySpeaker.listen()
}

코틀린의 인터페이스

  • 다른 언어와는 다르게 기본적인 구현 내용이 포함될 수 있다.
interface Pet {
    var category: String // abstract 키워드가 없어도 기본은 추상 프로퍼티
    fun feeding() // 마찬가지로 추상 메서드
    fun patting() { // 일반 메서드: 구현부를 포함하면 일반적인 메서드로 기본이 됨
        println("Keep patting!") // 구현부
    }
}

class Cat(override var category: String): Pet {
	override fun feeding() {
            println("Feed the cat a tuna can!")
        }
}
  • 게터를 통한 구현
interface Pet {
    var category: String
    val msgTags: String // val 선언 시 게터의 구현이 가능
        get() = "I'm your lovely pet!"
}
  • 인터페이스의 위임 사용
interface A {
    fun functionA(){}
}
interface B {
    fun functionB(){}
}
class C(val a: A, val b: B) {
    fun functionC(){
        a.functionA()
        b.functionB()
    }
}

class DelegatedC(a: A, b: B): A by a, B by b{
    fun functionC(){
        functionA() // A의 위임
        functionB() // B의 위임
    }
}        

데이터 클래스

  • 주 생성자는 최소한 하나의 매개변수를 가져야 한다.
  • 주 생성자의 모든 매개변수는 val, var로 지정된 프로퍼티여야 한다.
  • 데이터 클래스 abstract, open, sealed, inner 키워드를 사용할 수 없다.
data class Customer(var name: String, var email: String)
// 간단한 로직을 포함 하려면
data class Customer(var name: String, var email: String) {
    var jop: String = "Unknown"
    costructor(name: String, email: String, _jop: String): this(name,email) {
        job = _job
    }
    init {
        // 간단한 로직은 여기에
    }
}
  • 자동 생성되는 메서드들
    • equals()
    • hashCode()
    • copy()
    • toString()
    • componetN()

디스트럭처링(destructuring)

  • 객체가 가지고 있는 프로퍼티를 개별 변수들로 분해
val cus1 = Customer("Sean", "sean@mail.com")

val (name, email) = cus1
println("name = $name, email = $email")

// 특정 프로퍼티를 가져올 필요 없는 경우
val(_, email) = cus1

// componentN() 메서드 이용
val name2 = cus1.component1()
val email2 = cus1.component2()

// 객체 데이터가 많은 경우 for문의 활용
val cus1 = Customer("Sean", "sean@mail.com")
val cus2 = Customer("Sean", "sean@mail.com")
val bob = Customer("Bob", "bob@mail.com")
val erica = Customer("Erica", "erica@mail.com")

val customers = listOf(cus1, cus2, bob, erica) // 모든 객체를 컬렉션 List 목록으로 구성

for((name, email) in customers) { // 반복문을 이용해 모든 객체의 프로퍼티 분해
    println("name = $name, email = $email")
}

코틀린 내부 클래스

  • 중첩 클래스(nested class) : 객체 생성 없이 사용 가능
class Outer {
    val ov = 5
    class Nested {
        val nv = 10
        fun greeting() = "[Nested] Hello ! $nv" // 외부의 ov에는 접근 불가
    }
    fun outside() {
        val msg = Nested().greeting() // Outer 객체 생성 없이 중첩 클래스의 메서드 접근
        println("[Outer] : $msg, ${Nested().nv}") // 중첩 클래스의 프로퍼티 접근
    }
}

fun main() {
    // static 처럼 Outer의 객체 생성 없이 Nested객체를 생성 사용할 수 있음
    val output = Outer.Nested().greeting()
    println(output)
}
  • 이너 클래스(inner class) : 필드나 메서드와 연동하는 내부 클래스로 inner 키워드가 필요하다.
class A {
    ...
    inner class B { // 자바와 달리 inner 키워드 필요
        ... // 외부 클래스 A의 필드에 접근 가능
    }
}
// 정적 클래스처럼 사용한 코틀린의 중첩 클래스
class A{
    ...
    class B{ 
    // 코틀린에서는 아무 키워드가 없는 클래스는 중첩 클래스이며 정적 클래스 처럼 사용
    // 외부 클래스 A의 프로퍼티, 메서드에 접근할 수 없음
    }
}
  • 지역 클래스(local class) : 클래스의 선언이 블록에 있다면 지역 클래스이다.
class Smartphone(val model: String) {
    
    private val cpu = "Exynos"
    
    fun powerOn(): String {
        class Led(val color: String) { // 지역 클래스 선언
            fun blink(): String = "Blinking $color on $model" // 외부의 프로퍼티는 접근 가능
        }
        val powrStatus = Led("Red") // 여기에서 지역 클래스가 사용됨
        return powerStatus.blink()
    }
}
            
  • 익명 객체(anonymous object) : 이름이 없고 주로 일회용 객체를 사용하기 위해 object 키워드를 통해 선언된다.

부스트코스 코틀린강좌를 참고하였습니다.

0개의 댓글