Kotlin 추상 클래스(Abstract class), 인터페이스(Interface)

Notepad96

·

2020. 10. 4. 13:44

300x250

 

 

 

 

1. 추상 클래스(Abstract class)

추상 클래스는 동일하게 사용되는 프로퍼티나, 멤버함수는 사용할 수 있으며

 

동일한 기능의 다른 동작을하는 프로퍼티나 멤버함수는 오버라이딩하여 클래스의 따라 맞게 사용할 수 있다.

 

단, 추상 프로퍼티, 추상 멤버함수들을 모두 반드시 오버라이딩 해야만 한다.

 

 

abstract class Animal {
    abstract var name: String
    var sex: String = "male"
    abstract fun howling(): String
}

class Dog : Animal() {
    override var name: String = "gogy"
    override fun howling() = "war"
}
class Cat : Animal() {
    override var name = "navy"
    override fun howling() = "nya"
}

fun main() {
    var dog = Dog()
    var cat = Cat()
    println(dog.name)
    println(dog.sex)
    println(dog.howling())
    println("============")
    println(cat.name)
    println(cat.sex)
    println(cat.howling())
}

 

결 과

Animal이라는 추상 클래스를 선언하였다.

 

name은 추상 프로퍼티이며 howling은 추상 멤버함수이여 서브클래스에서 이를 오버라이딩하여 정의를 해주어야만 한다.

 

그의 반하여 sex 프로퍼티는 동일하게 사용하는 프로퍼티로서 클래스마다 재정의를 해줄 필요가 없다. 따라서 추상 프로퍼티로 정의하지 않았으며, Dog와 Cat에서 오버라이딩하지 않는다.

 

 

 

※ 본래 오버라이딩을 하기위해서는 open 키워드를 사용하여 해당 함수를 열어주었어야 했다. 하지만 abstract 키워드만 사용하여 오버라이딩하고 있는데, 이는 abstract가 open의 기능도 포함하고 있기 때문이다.

 

 

 

 

 


2. 인터페이스(Interface)

인터페이스는 프로퍼티를 반드시 재정의해야하는 것을 보장한다.

재정의를 보장하므로 인터페이스 내에서 초기화가 불가능하다.

 

멤버 함수의 경우 부모 인터페이스의서 정의가 되어있다면 반드시 재정의해야할 필요는 없다.

 

하지만 선언만되어 있을 경우 오버라이딩하여 구현을 해주어야만 한다.

 

 

interface Animal {
    var name: String
    // var sex: String = "male"
    fun howling(): String
}

class Dog : Animal {
    override var name: String = "gogy"
    override fun howling() = "war"
}
class Cat : Animal {
    override var name = "navy"
    override fun howling() = "nya"
}

fun main() {
    var dog = Dog()
    var cat = Cat()
    println(dog.name)
    println(dog.howling())
    println("============")
    println(cat.name)
    println(cat.howling())
}

 

인터페이스를 정의하기 위해서는 class없이 interface 키워드만을 사용하여 선언한다.

 

 

주석을 지우고 Animal 인터페이스 내부에서 sex 프로퍼티를 초기화하도록 시도하면 에러가 발생한다.

 

 

 

 


3. 인터페이스 다중 상속

클래스는 본래 다중 상속을 지원하지 않는다.

 

하지만 인터페이스는 다중 상속을 지원하며 이 때문에 문제가 발생할 수 있다.

 

 

만약 부모 인터페이스의 함수를 호출하고자 한다. 하지만 다중 상속받은 부모 인터페이스들이 동일한 이름의 함수를 갖고 있다면 호출이 어느곳으로 접근해야할지 모르게된다.

 

따라서 이 경우 이름을 따로 지정해주어야 한다.

 

interface Dog {
    fun howling():Unit = println("war")
}
interface Cat {
    fun howling():Unit = println("nya")
}

class DogCat: Dog, Cat {
    override fun howling() {
        super<Dog>.howling()
        super<Cat>.howling()
    }
}

fun main() {
    var dog = DogCat()
    dog.howling()
}

 

super<Dog> 를 통하여 Dog 인터페이스에 접근하며 super<Cat> 을 통하여 Cat 인터페이스의 접근하여 멤버 함수를 호출할 수 있다.

 

 

※ 만약 이름이 동일하지 않았다면 "super.howling()" 처럼 그냥 호출할 수 있다.

 

 

 

 


4. 참 조

 

 

Classes and Inheritance - Kotlin Programming Language

 

kotlinlang.org

 

 

 

Interfaces - Kotlin Programming Language

 

kotlinlang.org

 

 

300x250