[Kotlin] 상속 Inheritance, 인터페이스 Interface

Yeon·2023년 7월 8일
0

Android

목록 보기
7/9
post-thumbnail

상속 Inheritance

  • 클래스를 설계할 때 외부 클래스를 틀로 가지고 와서 제작하는 기법
  • 부모 클래스 (Super Class): 상속의 대상
    • 상속 가능한 class를 만들려면 open, abstract 키워드를 사용
      • open class: instance 생성o
      • abstract class: instance 생성x
  • 자식 클래스 (Sub Class): 상속을 사용
    • 부모 클래스에 존재하는 속성과 같은 이름의 속성을 가질 수 없음
    • 생성자 호출 시 반드시 부모 클래스 생성자가 먼저 호출됨
    • 파라미터를 받을 때 var, val을 붙이지 않고 일반 파라미터로 받음
      • var, val을 붙이면 속성으로 선언됨
      • 일반 파라미터로 받은 값들을 부모 클래스 생성자에 직접 넘겨줌
  • '자식 클래스( ): 부모 클래스( )' 방식으로 상속 받음
fun main() {
    var a = Animal("coco", 5, "강아지")
    var b = Dog("coco", 5)
    var c = Cat("mimi", 1)
    
    a.introduce()
    b.introduce()
    
    b.bark(
    c.meow()
}

open class Animal(var name: String, var age: Int, var type: String) {
    fun introduce() {
        println("나는 ${type} ${name}이고, ${age}살 이야.")
    }
}

class Dog(name: String, age: Int): Animal(name, age, "강아지") {
    fun bark() {
        println("멍멍")
    }
}

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

open

  • 기본적으로 Kotlin의 클래스는 최종 클래스이므로 상속할 수 없음
  • 클래스를 상속 가능하게 만들려면 open 키워드를 사용
open class Base    // Class is open for inheritance
  • 명시적 상위 유형을 선언하려면 클래스 상단에서 콜론 뒤에 유형을 배치
open class Base(p: Int)

class Derived(p: Int): Base(p)
  • 기본 생성자 o in 파생 클래스: 매개 변수에 따라 해당 기본 생성자에서 기본 클래스를 초기화할 수 있으며 초기화해야 함

  • 기본 생성자 x in 파생 클래스: 각 보조 생성자는 키워드를 사용하며 기본 형식을 초기화하거나 다른 생성자에게 위임해야 함. 이 경우 다른 보조 생성자가 기본 유형의 다른 생성자를 호출할 수 있음

class MyView: View {
    constructor(ctx: Context): super(ctx)
    
    constructor(ctx: Context, attrs: AttributeSet): super(ctx, attrs)
}

Any

  • Kotlin 모든 클래스의 최상위 클래스
  • methods
    ① equals( ): 다른 개체가 이 개체와 동일한지 여부를 나타냄
    open operator fun wquals(other: Any?): Boolean
    ② hashCode( ): 개체의 해시 코드 값을 반환
    open fun hashCode(): Int
    ③ toString( ): 개체의 문자열 표현을 반환
    open fun toString(): String

오버라이드 Override

  • 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것
  • 변수도 override로 재정의 할 수 있지만 주로 항수를 재정의하는데 사용
  • 재정의할 때 인자의 개수나 타입도 동일해야 함
  • 함수뿐만 아니라 변수도 open 키워드와 override 키워드를 사용해야 함
oepn class Animal(var name: String, var age: Int) {
    open fun cry() {
        println("울음 소리")
    }
}

class Dog(name: Sting, age: Int): Animal(name, age) {
    override fun cry() {
        println("멍멍")
    }
}

class Cat(name: String, age: Int): Animal(name, age) {
    override fun cry() {
        println("냐옹")
    }
}

오버라이딩 충돌 해결

상위 유형 목록에서 여러 유형을 선언할 때 동일한 메소드의 구현을 둘 이상 상속할 수 있음

// interface A, B 모두 foo 함수와 bar 함수 선언
interface A {
    fun foo() { print("A) }
    fun bar()    // 구현 로직이 없어 오류 발생
}

interface B {
    fun foo() { print("B")}
    fun bar() { print("bar") }
}


// override를 통해 오류 해결
class C: A {
    override fun bar() { print("bar") }
}


// interface A, B에서 상속한 모든 메서드를 구현
class D: A, B {
    override fun foo(){
        super<A>.foo()
        super<B>.foo()
    }
    
    override fun bar() {
        super<B>.bar()
    }
}

인터페이스 Interface

  • 추상화 함수의 선언과 메서드의 구현이 함께 포함되어질 수 있음
  • 클래스와 달리 인터페이스에서는 상태를 저장할 수 없음

인터페이스는 아래와 같이 선언하고 사용함

interface MyInterface {
    fun bar()
    fun foo() {
        // optional body
    }
}

인터페이스 구현

class Child: MyInterface {
    override fun bar() {
        // body
    }
}

인터페이스 상속

interface Named {
    val name: String
}

interface Person: Named {
    val firstName: String
    val latName: String
    
    override val name: String get() = "$firstName $latName"
}

data clas Employee (
    // implementing 'name' is not required
    override val firstName: String
    override val latName: String.
    val position: Positon
): Person

[참고 사이트]

"Interface", Kotlin
"[kotlin] 코틀린 차곡차곡 - 5. 클래스 - 상속과 인터페이스", 사바라다는 차곡차곡
"[Android / Kotlin] 상속", wys4475.log

0개의 댓글