[Kotlin] abstract class / interface

boogi-woogi·2023년 3월 27일
0
post-thumbnail

미션을 진행하면서 abstract class를 사용한 이유

오목 미션을 진행하면서 abstract classinterface의 차이에 대해서 생각해보았다.

나는 abstract classOmokPlayer를 상속하는 BlackStonePlayer, WhiteStonePlayer클래스를 생성했다. 여기서 내가 interface구현(implement)하는 것이 아닌 abstract class상속(inheritance)하도록 만든 이유는 무엇일까?

abstract class OmokPlayer{

    abstract val color: Color
    protected var state: PlayerState = PlayerState.Placing

    fun placeStone(
        currentBoard: Board,
        checkBoard: (Board) -> Unit,
        decidePoint: (latestStone: Stone?, currentColor: Color) -> Point
    ): Board {
        //돌을 두는 로직을 가지는 함수 
    }

    abstract fun toNextPlayer(): Player
    //다음 플레이어를 반환하는 함수

    abstract fun isPossibleToPlace(board: Board, placingPoint: Point): Boolean
    //특정 위치에 돌을 둘 수 있는지 없는지에 대한 함수
}

class BlackStonePlayer: OmokPlayer() {

    override val color: Color = Color.Black

    override fun isPossibleToPlace(board: Board, placingPoint: Point): Boolean {
        //33, 44, 놓으려고 하는 위치에 돌이 놓여있는지에 대한 함수
    }

    override fun toNextPlayer(): Player {
       //돌을 잘 두었으면 WhiteStonePlayer를 반환한다
    }
}

class WhiteStonePlayer : Player() {

    override val color: Color = Color.White

    override fun isPossibleToPlace(board: Board, placingPoint: Point): Boolean {
        //놓으려고 하는 위치에 돌이 놓여있는지에 대한 함수
    }

    override fun toNextPlayer(): Player {
        //돌을 잘 두었으면 BlackStonePlayer를 반환한다
    }
}
  • BlackStonePlayerWhiteStonePlayer의 중복되는 프로퍼티와 메서드
  • 추상화 해놓게 되면 다른 색깔의 플레이어가 새로 생겼을때 클래스를 추가, 확장을 위해
  • 같은 메세지인 isPossibleToPlace, toNextPlayer에 대해서 다르게 반응
  • 논리적으로 관련이 있는 클래스들의 계층 구조를 나타내기 위해

내가 abstract class를 사용한 이유이다.

interface를 사용해도 되지 않을까?

물론 interface 를 사용해 다형성을 이용하는 설계를 할 수도 있었을 것이다.

하지만 interfaceabstract class 의 가장 큰 차이는 논리적으로 관련이 있는 클래스들의 계층 구조를 형성하는 것이다. abstract class를 사용하기 위해서는 is-a 관계를 나타내는 상속(inheritance)을 사용하기 때문이다.

결론적으로 abstract class는 논리적 또는 의미적으로 관련이 있는 클래스들에서 다형성을 이용하고 싶을때 사용한다고 생각한다.

만약 interface를 사용했다면?

구현(implements)상속(inheritance)과 다르게 서로 논리적으로 관련이 적은 클래스들끼리도 필요에 의해 형제 타입처럼 묶어 버릴 수 있다. 필요에 따라서 자유롭게 붙였다 땠다 할 수 있는 것이 장점이다.

만약 YellowStonePlayer가 추가되었다고 하자. 그리고 BlackStonePlayerYellowStonePlayer는 돌을 놓을때 제한되는 위치에 대한 룰이 있다고 한다면 다음과 같이 필요에 따라서 ForbiddenPlacingRule이라는 interface를 두어 필요한 클래스에 붙였다 뗐다 하는 방식으로도 구현해 보는 방법도 있을것 같다.

결론

내가 왜 abstract class를 사용했을까에 대해서 생각해보면서 interface와의 차이에 대해서 학습했다.

  • abstract class는 구현부를 가지는 메소드, 초기화된 프로퍼티를 가질 수 있다.
  • interface는 구현부가 없는 메소드만 가질 수 있다.
  • ….

abstract classinterface를 사용할 때 표면적으로 드러나는 차이점 이외의 것들에 대해서도 한번씩 생각해보면 좋을것 같다.

profile
https://github.com/boogi-woogi

0개의 댓글