2010년 3월 24일 수요일

Interface Class #1 - 존재의 이유

Interface Class라고 들어봤나요? 도데체 뭘하는 녀석들일까요? 이상한 클래스입니다.

사실 필요성 같은거 별로 알고 싶지 않기도 하고 이런거 없이도 잘 살아왔어요.

사실입니다!

 

이렇게 말씀하시는 분 손한번 들어주세요.

Interface 클래스는 거참.. 말씀드리기가 어려운 내용입니다.

왜냐하면 논리적으로 "불필요하다"라고 단정적으로 이야기 할 수 없고

"반드시 필요하지!"라고 말하기도 애매한 내용일 수 있기 때문입니다.

 

하지만 개발자들은 Interface 클래스를 이용합니다. 심지어 저번에 포스팅했던 아이템 렌더러까지도요.

인터페이스들을 구현하지 않으면 아이템렌더러가 제대로 작동하지 않게 설계되었기 때문인데요.

그거 외에도 수많은 인터페이스 클래스들이 존재합니다.

 

왜 그럴까요? 왜!

 

아시모프님께서 좋은 설명을 해주셨는데요(관련글 : http://silverktk.tistory.com/134)

 

인터페이스를 쓰는 가장 큰 이유는 다중상속을 지원하지 않는 자바에서 다중상속의 장점을 가져오기 위해서입니다.

 라고 말씀하셨네요. 자바로 설명을 주셨지만 액션스크립트라고 크게 다르지 않습니다.

C개발하시는 분들이 종종 질문하시는 내용중에 하나인데요. "액션스크립트에서는 다중 상속이 안되느냐?"라고 물어보시곤 합니다.

 

다중상속이라함은 다른 여러 클래스를 다중으로 상속받게 하는 것인데 자바나 액션스크립트에서는 지원하지 않고 있지요. 대신 인터페이스 클래스라는 것을 이용하게 합니다. 이를 통하여 얻을 수 있는 장점은 부모 클래스에서 무조건적으로 받아내는 상속이라는 개념대신 자식 클래스에서 필요한 매서드를 구현하여 부모 클래스의 불필요한 부분을 걷어내고 자식 클래스에 맞게끔 새로 구현할 수 있게 된다는 것이지요.

 

그리고 보다 넓은 확장성을 기대할 수 있게 합니다. 예를 들어 이렇게 되겠지요.

 

IContent라는 인터페이스 클래스가 있고 안에는 3가지 메서드가 있다고 했을때 그것들을 구현한 ImageContent와 FLVContent, SWFContent는 기본적으로 play(), stop(), pause() 라는 메서드가 있게 됩니다. 의심할 여지가 없지요.

 

코드로 보면 이렇게 됩니다.

[code as3]
package classes.controls
{
import classes.controls.IContent;
import flash.display.Sprite;

public class ImageContent extends Sprite implements IContent
{
    public function ImageContent()
    {
        super();
    }

    public function play():void
    {
        //
    }

    public function pause():void
    {
        //
    }

    public function stop():void
    {
        //
    }
}
}
[/code]

예를 들어 위와같이 IContent를 구현해 내고 나면 저 클래스를 가져다 쓰는 곳에서는 이렇게 사용할 수 있게 됩니다.

 

[code as3]
package
{
import classes.controls.ImageContent;
import classes.controls.IContent;

import flash.display.DisplayObject;
import flash.display.Sprite;

public class Main extends Sprite
{
    public function Main()
    {
        super();

        if(!child)
        {
            child = new ImageContent();
        }

        IContent(child).play();
    }

    private var child:DisplayObject;
}
}
[/code]

 

위와 같이 코드를 작성할 수 있게 됩니다. 뭔가 좀 이상한 구석이 있으시다면 코드를 저렇게 만들어 두시고 컴파일해보시면 이해하실 수 있을까요.. child라는 녀석이 DisplayObject이지만 IContent를 구현한 ImageContent로 생성해 놓고 나중에 IContent로 캐스팅 할 수 있게 된다는 사실은 논리적으로 하자가 없지요.

 

게다가 만약에 IContent말고 예를들어 IDestroy같은 인터페이스 클래스가 있다고 가정했을 때

 

[code as3]
public class ImageContent extends Sprite implements IContent, IDestroy
[/code]

 

라고 해서 구현해 놓으면 나중에 IDestroy(child)라고 캐스팅할 수 있게 됩니다.

아, 물론 IDestroy(child).play() 이렇게 할 수는 없지요. IDestroy는 IContent와 다르니까요.

 

복잡하신가요? 오늘은 이정도로 맛만보구요. 담부터는 좀더 자세하고 섬세하게 알아보는 시간을 갖었으면 좋겠습니다.

1 개의 댓글:

오주헌 :

내용 잘 봤습니다. 인터페이스는 알고있어도 사용하는 방법에 대해서는 아직 서툰점이 많네요~ 많은 좋은글 부탁드립니다.