'인터페이스'에 해당되는 글 1건

  1. 2008.06.06 상속과 구현
AS3나 자바등과 같은 OOP언어의 특징은 상속과 구현이다. 상속은 앞서 테스트해본 사용자정의 클래스만들기 부분에서 Test클래스와 같이 부모를 Sprite라는 프레임 없는 무비클립을 상속받았고 Test2클래스는 Test클래스를 상속받았으므로 위의 두성분을 모두 포함하고 있다고 설명하였다. 이처럼 부모의 성질을 이어받는 것이 상속이다.

[ 상속 ]
우선 상속이라는 개념을 살펴보면 그림과 같은 가계도를 갖는다.
사용자 삽입 이미지
그림을 보면 최상위 클래스인 James라는 놈에게서 son1과 son2가 부모의 성질을 받아 만들어졌다.
빨간색 글씨부분은 부모클래스인 James의 성질을 이어받았기 때문에 따로 만들어 주지 않아도 실행이 가능해졌다. 그리고 son1의 경우에는 추가로 2개의 성질을 더 만들어 주어 양손잡이가 되었고 게임도 좋아하게 되었다.
son2의 경우에는 1개의 성질만 추가하였기 때문에 영화를 좋아하는 성질을 갖게되었다.

이처럼 기본기능이 있는 부모클래스를 상속받아 프로젝트에 맞는 부가적인 메서드를 추가로 개발하는것을 상속이라고 생각하면 되겠다.
* 부모에게서 받은 성질중에 고치고자 하고싶은 것은 override하면 된다.
가령 james의 곱슬머리()를 자식클래스에서 기능을 바꾸고자 한다면
override 곱슬머리(){
바꾸고자하는 머리스타일...
}
위처럼 기능을 재정의 하는것이다. (메서드의 재정의 override 참고)

[ 구현 ]
구현은 구조를 만들기 위해서 아주 중요한 부분이 된다.
개발을 하다보면 상속만 가지고는 어느 한계에 마주치게 되고...그 때 아쉽게 생각이 드는 것이 다중 상속이라는 것을 생각하게 된다...하지만 그것은 불가능한 것이기 때문에 Interface라는 것을 만들어 여러형태로 바라볼 수 있게 만드는 것이다. 가령 위그림에서 son1은 James의 아들이다. 하지만 James의 아내가 Jena라면 son1은 Jena의 아들이기도 하다. 하지만 이를 표현하기 위해서 그림과 같은 상속구조에서는
절대 Jena라는 클래스와 son1의 관계를 표현할수 없는 단방향 구조를 갖게된다. OOP의 장점이자 단점인 부분인 것 같다.

그러면 이러한 구성을 Interface로 풀어보자.
사용자 삽입 이미지
James에 관해서는 상속으로 고리가 연결되어있다. 하지만 상속은 단일 상속밖에 되지않으므로 Interface Jena를 만들어 이를 구현하고자 하는 클래스에서 구현(implements)하게 된다. 그러면 Son1과 Son2에는 James의 성질을 갖으면서 Jena의 성질도 포함하게 된다. 중요한 것은 나중에 이들을 부를(호출)때 James의 아들로 호출하여도 되고 Jena의 아들로 호출하여도 이 Son클래스들은 바라보게 된다는 것이다.

만약 이들을 코드로 본다면 다음과 같다.
Package는 생략...
public class Son1 extends James implements Jena
{
//Son1의 생성자(new로 호출했을 때 실행되는 부분)
public function Son1()
{

}
기타 필요한 메서드...
}


Jana의 코드
package
{
 public interface Jena
 {
jena의 설징을 결정할 메서드들 정의
 }
}
Jena는 인터페이스이다. 인터페이스는 항상 public이나 internal로 스코프를 갖게된다.
이들은 이들을 구현할 클래스를 성질을 구분짓기 위해 주로사용되고 인터페이스 내부에는 메서드만 정의해 놓는다. 상세코드는 구형하지않는다.
가령 Jena는 Beauty()이라는 속성만 가지고있다면 아래처럼 코딩한다.
package
{
 public interface Jena
 {
    function Beauty():void

 }
}

이처럼 실행문을 코딩하지 않는다. 이들의 실행문은 이를 받아 구현하는 Son1이나 Son2에서 필요에 따라 작성하면 된다. 단 인터페이스에서 함수가 있다면 해당  함수를 반드시 포함하고있어야한다.
public class Son1 extends James implements Jena
{
  public function Son1()
  {

  }
  function Beauty():void
  {
      필요하다면 기능 구현
  }
}

이렇게 된다면 Son1은 아름답다라는 성질도 갖게되는 것이다. 이 성질은 jena에게서 온것이다.
아쉬운점은 인터페이스에서 상세 구현이 불가능하므로 상속처럼 성질을 이어받으면 호출에서 실행시킬 때 따로 구현할 필요가 없지만 인터페이스는 그때, 그때 상세 코드를 구현하여야 한다..ㅜㅜ;;
하지만 이거라도 되는게 어딘가...

만약 다음과 같은 상황이 있다고 가정하여 보자.
사용자 삽입 이미지

그림을 보면 새를 상속받은 [독수리] , [닭] , [새인형]이라는 클래스가 3개 있다.
이들은 모두 새라고 생각할 수 있다. 이제 이들을 구분지어 보면 누가 "날 수있는 것 모이세요!"하고 외쳤다. 그럼 독수리만 모이게 될것이다. 그럼 "소릴 낼수 있는것 모이세요!"라고 한다면 독수리와 닭이 모일것이며 "새들은 모이세요!"한다면 독수리,닭,새인형 모두 모일 것이다.. 이것은 클래스의 성질을 가지고 구분지을 수 있다는 말이다.

가령 화면에 객체들이 흩어져있다. 이들을 드래그하여 여러개 선택한 다음에 지우기 버튼을 눌러서 지우려고 한다. 그럼 지워질 수 있는 객체는 del()이라는 메서드가 실행되겠지만 지울수 없는 객체는 del()이라는 메서드가 포함되어 있질 않아서 에러를 발생할 것이다. 그럼 del이 있는 객체만 골라서 실행해야하는데
if( 선택된 객체 is Removable ){
    선택된 객체.del()
}
과 같이 객체의 성질을 검사하여 조건문에 의해 선택적으로 실행할 수 있다.
* Removable은 del()을 선언한 인터페이스이다. Removable인터페이스를 implements한 객체는
 반드시 del()이라는 메서드를 구현해 놓아야 하므로 조건식에 만족한다면 del()을 실행시킬 수 있다.






Posted by 버터백통