phantasmicmeans 기술 블로그

6. Kotlin - Class Inheritance 본문

Programming/Kotlin

6. Kotlin - Class Inheritance

phantasmicmeans 2021. 1. 22. 12:53

Class Inheritance

  • kotlin의 최상위 클래스는 Any
  • 클래스에 상위타입을 선언하지 않으면 Any가 상속됨
  • Any는 java의 Object와 다른 클래스임..
    • equlas, hashcode, tostring만 있음
class Example1()  // 암시적 Any 상속
class Example2() : Any() // 명시적 Any 상속 

open

  • open 은 java final과 반대임
  • open class는 다른 클래스가 상속할 수 있음
  • 기본적으로 kotline의 모든 classs는 final 임

상속

  • 명시적으로 상위타입을 선언하려면, 클래스 헤더의 콜론 뒤에 상위 타입을 선언하면 되며, 부모 클래스는 open keyword 필요
  • 파생 클래스에 primary constructor가 있으면, 상위 타입의 생성자를 호출하여 초기화 가능
open class Base(p: Int) 
class Derived(p: Int) : Base(p)
  • 파생클래스에 primary constructor가 없다면, 각각의 secondary constructor에서 super를 이용해 초기화하거나, 다른 constructor에게 상위 타입을 초기화 할 수 있게 delegate 해야한다.
class MyView: View {
    constructor(): super(1) // 상위 클래스 super 

    constructor(ctx: Int) : this() // 첫번째 secondary constructor 사용 

    constructor(ctx: Int, attrs: Int): super(ctx, attrs)
}

Overriding Methods

  • subclass에서의 method override
  • 상위 클래스, 상위 메소드 모두 open keyword를 포함해야함
  • final class에 open method를 만드는건 의미 없음. no effect
open class Shape {
    open fun draw() { /* do something */ }
    fun fill() { }
}

class Circle() : Shape() {
    override fun draw() { /* do something */ }
}

fun main(args: Array<String>) { }

re-overriding 을 금지시키고 싶다면 final keyword를 사용하면 된다.

open class Rectangle(): Shape() {
    final override fun draw() { }
}

Overriding Properties

  • 메소드 오버라이딩과 매우 비슷하다. 상위 클래스 프로퍼티들 중 하위 클래스에서 재 선언된 프로퍼티는 꼭 override keyword를 필요로한다.
open class Shape {
    open fun draw() {}
    fun fill() { }

    open val vertexCount: Int = 0
}

class Circle() : Shape() {
    override fun draw() { }
    override val vertexCount: Int = 1
}

open class Rectangle(): Shape() {
    final override fun draw() { }
    override val vertexCount: Int = 4
}

fun main(args: Array<String>) {
    var circle:Circle = Circle()
    var rectangle: Rectangle = Rectangle()

    println(circle.vertexCount)
    println(rectangle.vertexCount)
}

인터페이스에서도 아래와 같이 사용 가능하다.

interface ShapeInterface {
    val vertexCount: Int
}

class RectangleExtendI(override val vertexCount: Int = 4) : ShapeInterface

class Polygon: ShapeInterface {
    override val vertexCount: Int = 0
}

Derived class Initilization order

  • derived(파생) class 가 인스턴스화 될 때, base class의 intialization이 먼저 행해진다.
  • 이후 derived class intialization logic이 실행된다.
open class Base(val name: String) {
    init {
        println("init base")
    }

    open val size: Int = name.length.also { println("Intializing size in Base: $it") 
}

class Derived (
    name: String,
    val lastName: String,
) : Base(name.capitalize().also { println("Argument for base : $it") }) {

    init {
        println("Initializing Derived")
    }

    override val size: Int = (super.size + lastName.length).also { println("intializing size in derived") }
}

fun main(args:Array<String>) {
    var derived: Derived = Derived("sangmin", "lee")
}

Calling the superclass implementation

  • super.~~ keyword로 super class의 property, function 접근
  • inner class에서 super 클래스들에 접근하는 방법은 super@Outer(class name) 으로 접근한다.
open class RectangleO {
    open fun draw() {
        println("Drawing a rectangle")
    }

    val borderColor: String get() = "black"
}

class FilledRectangle: RectangleO() {
    override fun draw() {
        val filler = Filler()
        filler.drawAndFill()
    }

    val fillColor: String get() = super.borderColor

    inner class Filler {
        fun fill() {
            println("Filling")
        }

        fun drawAndFill() {
            super@FilledRectangle.draw() // calls Rectangle's implementation of draw()
            fill()
            println("Drawn a filled rectangle with color ${super@FilledRectangle.borderColor}")
        }
    }
}

Overriding Rules

kotlin에서 상속을 구현할 때 아래와 같은 rule을 따른다.

  • multiple implementation 의 경우, 동일한 멤버(프로퍼티, 함수 등)가 존재하면 아래처럼 super<T>.을 사용하여 super class를 호출할 수 있다.
open class RectangleRule {
    open fun draw() {}
}

interface PolygonRule {
    fun draw () {}
}

class Square() : RectangleRule(), PolygonRule {
    // The compiler requires draw() to be overridden:
    override fun draw() {
        super<RectangleRule>.draw() // call to Rectangle.draw()
        super<PolygonRule>.draw() // call to Polygon.draw()
    }
}

'Programming > Kotlin' 카테고리의 다른 글

8. Kotlin - Backing Field  (0) 2021.01.22
7. Kotlin - Properties  (0) 2021.01.22
5. Kotlin - Class  (0) 2021.01.22
4. Kotlin - Return and Jumps  (0) 2021.01.22
3. Kotlin - Control-Flow  (0) 2021.01.22
Comments