개발(Android)/kotlin syntax

[Kotlin syntax] Inheritance

shinyelee 2022. 5. 23. 16:11

[코틀린 문법] 상속

// Inheritance(상속) //
// 자식 클래스가 부모 클래스의 멤버를 물려받음

fun main() {

    var a = Animal("휴지", 5, "강아지")
    var b = Dog("휴지", 5)

    // Animal 클래스로부터 "강아지" 속성을 상속받음
    // -> b에서 "강아지" 생략해도 a와 b의 속성이 똑같음
    a.introduce()
    b.introduce()

    // bark는 Dog 클래스에만 해당함
//    a.bark()
//    Kotlin: Unresolved reference: bark
    b.bark()

    var c = Cat("감쟈", 1)

    c.introduce()
    c.meow()

}

// Super Class(수퍼/부모 클래스) //
// 물려주는 쪽
// class 앞에 open 붙여줘야 상속 가능
open class Animal (var name: String, var age: Int, var type: String)
{
    fun introduce() {
        // this 생략 가능
        println("저는 ${type} ${name}이고, ${age}살 입니다.")
    }
}

// 상속 규칙 //
// 1. 서브 클래스는 수퍼 클래스에 존재하는 속성과 같은 이름의 속성을 가질 수 없음
// -> var, val 등을 붙이면 클래스 자체 속성으로 선언되기 때문에 일반 파라미터로 받아야 함
// 2. 서브 클래스가 생성될 때 수퍼 클래스의 생성자가 호출되어야 함

// Sub Class(서브/자식 클래스) //
// 물려받는 쪽
class Dog (name: String, age: Int) : Animal (name, age, "강아지")
{
    fun bark() {
        println("멍멍")
    }
}

class Cat (name: String, age: Int) : Animal (name, age, "고양이")
{
    fun meow() {
        println("야옹")
    }
}

// 상속 보충설명 (1)

fun main() {

}

// 자바와 달리 코틀린에서는 상속해 주는 class 앞에 open을 붙여줘야 함
class Human(val name : String = "anonymous") {

    constructor(name : String, age : Int) : this(name) {
        println("My name is ${name}, and ${age} years old")
    }

    init {
        println("인스턴스 생성할 때 함께 실행됨")
    }

    fun eatingCake() {
        println("yummy!")
    }

    fun singASong() {
        println("상속 전 : lalala")
    }

}

//Kotlin: This type is final, so it cannot be inherited from
//class Korean : Human() {}
// 상속 보충설명 (2)

fun main() {

    val korean = Korean()
//    인스턴스 생성할 때 함께 실행됨

    korean.singASong()
//    상속 전 : lalala

}

// open 붙여줌
open class Human(val name : String = "anonymous") {

    constructor(name : String, age : Int) : this(name) {
        println("My name is ${name}, and ${age} years old")
    }

    init {
        println("인스턴스 생성할 때 함께 실행됨")
    }

    fun eatingCake() {
        println("yummy!")
    }

    // 자바와 달리 코틀린에서는 상속해 주는 function 앞에 open을 붙여줘야 함
    fun singASong() {
        println("상속 전 : lalala")
    }

}

class Korean : Human() {

//    Kotlin: 'singASong' in 'Human' is final and cannot be overridden
//    override fun singASong() {
//        println("상속 후 : 라라라")
//    }

}
// 상속 보충설명 (3)

fun main() {

    val korean = Korean()
//    인스턴스 생성할 때 함께 실행됨

    // 상속됨
    korean.singASong()
//    상속 후 : 라라라

}

open class Human(val name : String = "anonymous") {

    constructor(name : String, age : Int) : this(name) {
        println("My name is ${name}, and ${age} years old")
    }

    init {
        println("인스턴스 생성할 때 함께 실행됨")
    }

    fun eatingCake() {
        println("yummy!")
    }

    // open 붙여줌
    open fun singASong() {
        println("상속 전 : lalala")
    }

}

class Korean : Human() {

    override fun singASong() {
        println("상속 후 : 라라라")
    }

}
// 상속 보충설명 (4)

fun main() {

    val korean = Korean()
//    인스턴스 생성할 때 함께 실행됨

    korean.singASong()
//    상속 전 : lalala
//    상속 후 : 라라라

}

open class Human(val name : String = "anonymous") {

    // 위와 동일

}

class Korean : Human() {

    override fun singASong() {
        // 상속 전 메서드와 상속 후 메서드를 모두 쓰고 싶다면
        // super.메서드명
        // 형태로 활용하면 됨
        super.singASong()
        println("상속 후 : 라라라")
    }

}
// 상속 보충설명 (5)

fun main() {

    val korean = Korean()
//    인스턴스 생성할 때 함께 실행됨

    korean.singASong()
//    상속 전 : lalala
//    상속 후 : 라라라
//    I'm anonymous

}

open class Human(val name : String = "anonymous") {

    // 위와 동일

}

class Korean : Human() {

    override fun singASong() {

        super.singASong()
        println("상속 후 : 라라라")
        // 상속 받았기 때문에 Human 클래스의 매개변수(파라미터)를 받아옴
        // name 기본값이 "anonymous"이므로
        // I'm anonymous
        // 를 출력함
        println("I'm ${name}")

    }

}

참고

반응형