카테고리 없음

코틀린 클래스 상속 완전정복

slowbooktech 2022. 5. 23. 18:02

1. 상속
기존에 만들어진 클래스에서 여러 요소가 반복될 때, 새로운 함수를 추가하고 싶을 때 용이하다.

생성자와 마찬가지로, 반복되는 값을 아예 지정할때도 쓰인다.

ㅣ기본함수, 클래스 기초

fun main() {
    var a = Latte("hot", "medium", 5)
    a.printMenu()
}


class Latte(var latteTemperature:String, var size: String, var num : Int){
//    init은 함수 () {} 아니고 그냥 초기화깍두기
    init{
        println("\n please wait. We are making beverages \n")
    }
    constructor(latteTemperature : String, size : String) : this(latteTemperature, size,2){
        println("\n Using second CONSTRUCTOR \n")
    }
    fun printMenu(){
        println("you ordered $num ${this.latteTemperature} latte ${this.size} ")
    }
}

ㅣ상속

fun main() {
    var a = Latte("hot", "medium", 5)
    a.printMenu()
    
    var b = HotLatte("large",1)
    b.printMenu()
    
    val c = IceLatte("small",30)
    c.printMenu()
}


open class Latte(var latteTemperature:String, var size: String, var num : Int){
    init{
        println("please wait. We are making beverages \n")
    }
    constructor(latteTemperature : String, size : String) : this(latteTemperature, size,2){
        println("\n Using second CONSTRUCTOR \n")
    }
    //this X
    fun printMenu(){
        println("you ordered $num ${latteTemperature} latte ${size} \n\n")
    }
}

class HotLatte(size: String, num: Int) : Latte("HOT", size, num){
    init{
            println("compiler entered hotlatte class\n")
    }
}
class IceLatte(size: String, num: Int) : Latte("ICE", size, num){
    init{
            println("compiler entered icelatte class\n")
    }
}

ㅣ코드 결과

ㅣ코드 설명
1) 인스턴스

fun main() {
    var a = Latte("hot", "medium", 5)
    a.printMenu()
    
    var b = HotLatte("large",1)
    b.printMenu()
    
    val c = IceLatte("small",30)
    c.printMenu()
}

메인함수에서 세 인스턴스를 만들고 각각의 클래스를 이용했다. 이때, printMenu 는 라떼 클래스 안의 메서드이지만 해당 클래스를 상속받은 클래스들에서도 사용할 수 있다.
핫 라떼랑 아이스라떼 클래스는 이미 라떼의 온도가 정해져있으므로 생성자에 따라 음료 크기랑 수량만 넣어주었다.

2) 부모 클래스

open class Latte(var latteTemperature:String, var size: String, var num : Int){
    init{
        println("please wait. We are making beverages \n")
    }
    constructor(latteTemperature : String, size : String) : this(latteTemperature, size,2){
        println("\n Using second CONSTRUCTOR \n")
    }
    //this X
    fun printMenu(){
        println("you ordered $num ${latteTemperature} latte ${size} \n\n")
    }
}

super class인 Latte 클래스는 open을 통해 상속 가능하도록 열어준다. 클래스 안에서 두번째 생성자가 라떼 온도랑 사이즈만 받고 있고, 수량을 2로 정해둔 상태기때문에 만일 인스턴스가 수량 값을 정하지 않으면 항상 2잔을 출력하게 될것이다. 입력하면 그 값을 출력한다.

클래스 내의 함수에서 출력을 사용할 때는 ${this.latteTemperature} 로 사용하지 않는다. 이미 등록된 프로퍼티고 클래스 내에서 참조하는 것이므로 $ {프로퍼티} 를 출력하면 된다.

3) 자식 클래스

class HotLatte(size: String, num: Int) : Latte("HOT", size, num){
    init{
            println("compiler entered hotlatte class\n")
    }
}
class IceLatte(size: String, num: Int) : Latte("ICE", size, num){
    init{
            println("compiler entered icelatte class\n")
    }
}

생성자에서 데이터자료형만 알려주고, 상속받을 클래스를 : 를 통해 참조해준 후 값을 넣는 괄호 안에는 반복되는 값은 바로 대입한다.

더보기

클래스 자식클래스명 (파라미터 : 데이터자료형) : 부모클래스명 (넣을 값 혹은 파라미터) { }



다음은 추가로 공부한 영상 속 코드이다.

https://youtu.be/Mpn-kGFxB84?list=PLQdnHjXZyYadiw5aV3p6DwUdXV2bZuhlN

위의 코드에서 open된 class Animal을 상속받은 dog, cat 클래스는 각 클래스 안에서 각자의 메서드를 가지므로 인스턴스로 받아 해당 메서드를 특정 목적으로 사용하기 좋다.

animal 클래스로 만들어진 a 인스턴스는 다른 문자열이 들어갈 수 있으므로 개도, 고양이도, 호랑이도 될수있지만 dog 클래스로 만들어진 b 인스턴스는 animal 클래스를 상속받되 개가 지정되어있으므로 다른 동물이 될 수 없다.

dog 와 cat 클래스는 모두 아무런 지정 없이 animal 이 가진 메서드를 활용할 수 있다.

죽, 상속받은 클래스 dog과 cat은 인스턴스에 담길 때 상속된 클래스 animal 의 메서드에 접근할 수 있는 상태이다.