Kotlin으로 코딩을 하다 보니까 문득 이런 생각이 들었다
" interface와 abstract class는 생각해보면 다른 클래스에게 자신의 추상 메서드를 상속시켜서 자식 클래스에게 추상 메서드를 재정의하게 하는 것인 것 같은데 이 둘은 무슨 차이로 나눠 놓은 걸까"
이 부분이 궁금해서 직접 작성하면서 회고해보려고 한다
- 공통점
1. 이 둘은 모두 추상 메서드를 받을 수 있기 때문에 자식 클래스에서 반드시 추상 메서드를 재정의 해야 하는 공통점이 있다
예를 들어서
package org.example
//추상 클래스 선언
abstract class Calculator{
//추상 함수 선언
abstract fun result(num1:Int, num2:Int):Int
}
//인터페이스 구현으로도 위와 같은 구현을 할 수 있다
//interface Calculator2 {
// fun result(num1: Int, num2: Int): Int
//}
//하위 클래스 들에서 Calculator 클래스 상속
class AddOperation: Calculator() {
//추상 함수 재정의
override fun result(num1: Int, num2: Int):Int {
return num1 + num2
}
}
// ... 이하 생략
위와 같이 abstract 함수만 정의가 되어 있을 경우에는 interface를 써도 기능적인 동작은 정상 동작을 하는 것을 확인할 수 있다
하지만 이 둘은 위의 관점에서 봤을 때는 비슷 할 수도 있지만 엄밀히 다르다는 차이점이 있다 어떤 차이점이 있을까
1. 자식 클래스는 여러개의 interface를 상속을 받을 수 있지만 abstract 클래스는 여러개 상속 받을 수 없다
//추상 클래스 선언
abstract class Calculator{
//추상 함수 선언
abstract fun result(num1:Int, num2:Int):Int
}
//다른 추상 클래스 선언
abstract class Calculator2{
//추상 함수 선언
abstract fun result2(num1:Int, num2:Int):Int
}
//하위 클래스 에서 2개 이상의 추상클래스 상속을 받을 수 없다
class AddOperation: Calculator(), Calculator2() {
//추상 함수 재정의
override fun result(num1: Int, num2: Int):Int {
return num1 + num2
}
}
//Only one class may appear in a supertype list 컴파일 오류 발생
//상위 클래스는 하나만 받을 수 있다는 컴파일 오류
// ... 이하 생략
위의 사례에서 보듯이 Only one class may appear in a supertype list 오류가 발생하면서 2개 이상의 클래스를 받을 수 없게 된다
그러나 interface는 여러개를 상속 받아도 상관이 없는 것을 확인 할 수 있다
//인테페이스 선언
interface Calculator{
fun result(num1:Int, num2:Int):Int
}
//다른 다른 인터페이스 선언
interface Calculator2{
fun result2(num1:Int, num2:Int):Int
}
//하위 클래스 에서 2개 이상의 추상클래스 상속을 받을 수 없다
class AddOperation: Calculator, Calculator2 {
//추상 함수 재정의
override fun result(num1: Int, num2: Int):Int {
return num1 + num2
}
override fun result2(num1: Int, num2: Int):Int {
return num1 + num2
}
}
// 컴파일 오류 없음
// ... 이하 생략
* Tip : interface 여러개와 abstract class 하나만 상속을 받는 부분은 가능하다
2. 모든 메서드가 자동으로 추상 메서드가 되는 interface와는 달리 abstract class는 추상 메서드와 일반 메서드를 선택해서 구현이 가능하다
//추상 클래스 선언
abstract class Calculator{
//추상 함수 선언
abstract fun result(num1:Int, num2:Int):Int
fun language(){
println("언어입니다")
}
}
//인터페이스 선언
interface Calculator2{
fun result2(num1:Int, num2:Int):Int
}
위와 같이 추상 메서드에서는 추상적인 함수를 제외한 정식적인 기능을 가진 함수를 구현할 수 있지만 interface는 추상적인 함수만 구현이
가능하다는 차이점이 있다
- 어떤 식으로 사용하는 것이 좋을까??
- abstract 클래스는 공통적인 기능을 필요로 하고 추가적인 기능 로직이 다른 경우에 사용하는 것이 좋다
- interface는 클래스의 전체적인 기본 틀을 잡을 때 사용하는 것이 좋다
오늘의 결론
- abstract 클래스와 interface는 서로 다른 구조를 가지고 있지만 비슷한 구현을 할 수 있다
- abstract 클래스는 자식 클래스가 공통적인 기능을 가지고 있고 세부 기능만 자식 클래스가 구현하면 되는 경우 사용 하는 것이 좋다
- interface는 큰 틀에서 기본 기능을 구현할 때 사용하는 것이 좋다
'Kotlin' 카테고리의 다른 글
(Kotlin) JPA JPQL orderby 절 적용이 안되는 문제 (0) | 2024.05.21 |
---|---|
(Kotlin) 상수를 다루는 클래스 enum 클래스란?? (0) | 2024.04.30 |
(Kotlin) 어렵지만 쓰다보면 편한 Scope 함수에 대해 알아보자 (0) | 2024.04.27 |
(Kotlin) java.lang.unsupportedclassversionerror 애러 해결 (0) | 2024.04.22 |