인터페이스 (Interface) 란
인터페이스에는 abstract로 정의된 추상메서드나 일반메서드가 포함된다.
추상클래스처럼 프로퍼티를 통해 상태를 저장할 수 없고 선언만 가능하다.
인터페이스도 마찬가지로 객체를 생성할 수 없고 하위 클래스를 통해 구현 및 생성해야한다.
인터페이스를 사용하는 이유?
추상클래스를 사용할 때의 제한을 생각해보자. 하위클래스는 상속을 하나만 허용한다는 단점이 있다.
또한 상위클래스와 하위클래스의 강한 연관이 생기면서 상위클래스의 영향을 그대로 받게된다.
그래서 상위클래스가 수정되었을 때 하위 클래스를 일일이 확인하기 어려운 경우 부작용이 발생할 수 있는것이다.
인터페이스는 클래스가 아니다. 그래서 상속의 개념이 아닌 구현의 개념이라 구현클래스 (하위클래스)와
강한 연관을 가지지 않는다. 인터페이스는 원하는 만큼 구현클래스에 붙여서 필요한 메서드를 구현해 나가면 된다.
설령 인터페이스가 수정된다고 해도 구현클래스는 큰 영향이 없다.
interface 사용 예시
package com.example.demo.`interface`
interface Pet {
var category: String // abstract 키워드가 없어도 기본은 추상 프로퍼티
val msgTags: String
// val 선언시 게터의 구현이 가능하다.
get() = "I'm your lovely pet!"
var species: String
fun feeding() // 마찬가지로 추상 메서드
fun patting() { // 일반메서드: 구현부를 포함하면 일반적인 메서드로 기본이 됨
println("Keep patting!") // 구현부
}
}
class Cat(name: String, override var category: String) : Pet, Animal(name) {
override var species: String = "cat"
override fun feeding() {
println("Feed the cat a tuna can!")
}
}
open class Animal(val name: String)
// feeding의 구현을 위해 인터페이스 Pet지정
class Dog(name: String, override var category: String) : Animal(name), Pet {
override var species: String = "dog"
override fun feeding() {
println("Feed the dog a bone")
}
}
class Master {
fun playWithPet(pet: Pet) { // 애완동물 타입에 따라 오버로딩되어서 같은 함수명 사용가능
println("Enjoy with my ${pet.species}")
}
}
fun main() {
val master = Master()
val cat = Cat("coco", "small")
val dog = Dog("sarang", "small")
master.playWithPet(dog)
master.playWithPet(cat)
}
do.it 코틀린 프로그래밍 308쪽까지 인터페이스 내용.