본문 바로가기
Programming/Kotlin

[Kotlin] 코틀린 뽀개기 - 추상클래스 & 인터페이스

by 코딩의성지 2019. 12. 2.

하이 ~~ 여러분

 

우리 어서 코틀린 기본 공부 끝내고 같이 앱을 만들어보자 ..!

 

일단 여기까지 글을 읽고 있는 자신에게 크게 박수한번 쳐주자!! 의지가 대단한 것 같다 ㅎㅎㅎ

 

자 오늘은 추상클래스와 인터페이스를 공부할 것이다. 어떻게 보면 비슷한 개념이랑 같이 묶었다.

 

추상클래스 (Abstract Class)

 

추상클래스는 아직 구현되지 않고 선언만 된 추상메서드를 가지고 있는 클래스이다. 이 추상클래스는 메서드가 구현되지 않아서 이 클래스를 직접 객체로 만들 수는 없다! 반드시!! 반드시!! 상속을 받는 자식클래스 (SubClass) 가 있어야한다. 추상클래스는 상속을 통해 생성될 자식클래스에서 메서드 오버라이딩에 강제성을 부여하기 위해 사용된다.

 

예제를 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fun main(args : Array<String>) {
    var tempClass : AbstractClass = SubClass()
    tempClass.generalMethod()
    tempClass.abstractMethod()
}
 
open abstract class AbstractClass {
 
    //자식 클래스에서 그냥 사용할 수 있는 일반 메서드
    fun generalMethod () {
        println("일반 메서드")
    }
 
    //자식 클래스에서 오버라이딩 해야 사용할수 있는 추상 메서드
    open abstract  fun abstractMethod()
}
 
class  SubClass : AbstractClass() {
    override fun abstractMethod() {
        println("추상 메서드 구현")
    }
}
 
 

예제 소스 처럼 추상클래스에서는 바디가 구현된 일반 메서드도 구현이 가능하다. 그리고 추상 메서드는 서브클래스에서 Overriding 해서 사용하면 된다. 이 예제를 돌려보면 ...!

 

 

이렇게 결과가 나온다. ㅎㅎ 꼭 한번 직접 코딩해보길 권한다.

 

인터페이스 (Interface)

 

인터페이스는 다소 추상적인 개념이다. 우리는 보통 프로젝트를 개발할 때 설계를 한다. 이때 여러 인터페이스를 구현하면 각 인터페이스 타입을 가진 객체를 생성할 수 있고 이를 통해 인터페이스에 정의된 메서드 호출이 가능하다.

 

인터페이스 역시 추상클래스처럼 추상메서드 뿐만 아니라 바디가 구현된 일반 메서드도 넣을 수 있다. (Java 8.0 이상 부터는 인터페이스안에 일반 메서드 구현이 가능해졌다.) 

 

그리고 인터페이스를 사용하면 협업이 가능해진다. 이런 역할을 하는 메서드를 만들어줘 하면서 인터페이스를 제공해주면 개발자는 어떤 방식이든 구현 (Override) 해 주기만 하면된다. 물론 잘 구현해야 좋은 프로젝트가 되겠지만 ..!

 

자 예제를 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fun main (args :Array<String>) {
    // 정의한 인터페이스 (InterfaceExample) 타입의 객체 생성
    // 인터페이스는 직접 생성이 불가능하다. 해당 인터페이스를 구현한 클래스로 생성
    var tempClass : InterfaceExample = GeneralClass()
    useInterfaceExample(tempClass)
}
 
interface InterfaceExample {
    fun generalMethod() {
        println("InterfaceExample 에서 구현된 일반 메서드 입니다")
    }
    fun abstractMethod()
}
 
class GeneralClass : InterfaceExample {
    override fun abstractMethod() {
        println("GeneralClass 에서 구현된 추상 메서드 입니다")
    }
}
 
fun useInterfaceExample(ife : InterfaceExample) {
    ife.generalMethod()
    ife.abstractMethod()
}
 
 
 
s

음 ... 이렇게만 보면 ....??? 왠지 Abstract 메서드와 굉장히 비슷하다고 생각할 수 있다. 일단 실행시켜보자.

 

 

 

추상클래스 vs 인터페이스

 

이 애매모호함을 확실히 내가 해결해 주겠다. 다만 내가 객체지향언어를 공부하면서 느낀 점이니 .... 사실과 다를수 있음에 주의해주길 부탁한다.

 

내가 생각하기에 추상클래스는 abstract 메서드가 하나 이상있는 클래스이다. 추상클래스의 경우 상속받는 자식클래스는 반드시 추상클래스의 추상메서드를 구현해야한다고 했다. 그러니깐 추상클래스는 필수적으로 구현해야할 메서드가 딱 있을때 쓰면 된다.

 

인터페이스는 구현하기전에 메서드에 대해 명세서를 작성해 놓은 느낌이다. 인터페이스를 상속받는 클래스에서는 반드시 인터페이스에 있는 추상메서드를 다 구현해야한다.

그리고 상클래스는 단일 상속만 가능한데 터페이스는 여러개의 인터페이스를 구현할수 있다. 즉 다중 상속이 가능하다.

 

아래는 다중 상속에 대한 예제이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
fun main (args :Array<String>) {
    var tempClass1 : Interface1 = TempClass()
    tempClass1.generalMethod1()
    tempClass1.abstractMethod1()
 
    var tempClass2 : Interface2 = TempClass()
    tempClass2.generalMethod2()
    tempClass2.abstractMethod2()
}
 
interface Interface1 {
    fun generalMethod1() {
        println("Interface1 에서 구현된 일반 메서드 입니다")
    }
    fun abstractMethod1()
}
 
interface Interface2 {
    fun generalMethod2() {
        println("Interface2 에서 구현된 일반 메서드 입니다")
    }
    fun abstractMethod2()
}
 
class TempClass : Interface1, Interface2 {
    override fun abstractMethod1() {
        println("TempClass 에서 구현된 Interface1의 추상 메서드 입니다")
    }
 
    override fun abstractMethod2() {
        println("TempClass 에서 구현된 Interface2의 추상 메서드 입니다")
    }
}
 
r
 

TempClass를 보면 Interface1, Interface2 두개의 인터페이스가 구현되어 있는 걸 볼 수 있다. 다중상속은 이렇게 사용하면 된다. 이 소스를 실행시켜보면 ...

 

이런 결과가 나온다.

 

아 !!! 중요한 설명을 하나 안하고 갈 뻔 했다. 인터페이스를 잘 이해하려면 다형성(polymorphism) 에 대한 개념을 잘 이해해야한다. 오늘은 아주 간단하게 설명하겠다. 

 

'바람의 나라' 라는 게임을 예로 들겠다.

 

이 게임은 선택할 수있는 '직업'이 있다.

이 '직업' 을 '인터페이스'라고 생각하자.

 

그리고 이 각 캐릭터는 '공격한다, 마법을사용하다.' 등의 '행위'를 할 수 있다.

이걸 '메서드'라고 생각하자.

 

그리고 레벨 5가 되면 '전사, 도적, 주술사, 도사' 로 직업을 선택할 수 있다.

이걸 구현할 '클래스' 라고 생각하자.

 

각 직업마다 공격하는 방식이나 마법을 사용하는 방식이 다르다. 이건 다르게 구현을 해줘야한다.

( 즉 Overriding 해줘야한다는 말)

 

이렇게 직업마다 여러가지 형태로 구현을 할 수가 있다. 이게 바로 다형성이다. ㅎㅎ 쉽지?

 

아 글이 너무 길어졌다.. 오늘은 여기까지만 하자 !! 그럼 즐거운 코딩하자 친구들!!

반응형

댓글