Tip And Tech2008. 6. 7. 12:07

AS3에는 Event클래스나 MouseEvent클래스 KeyBoardEvent , FocusEvent등 다양한 이벤트들은 제공하여 준다, 이 이벤트 클래스를 활용하여 보기 좋게 이벤트 이름을 설정하거나 필요한 값을 이벤트에 실어서 보낼수 있게 만들어 보자.

가령 섬네일을 눌렀을 때 섬네일은 버튼이며 마우스 이벤트를 사용하면 된다.
thumb.addEventListener( MouseEvent.MOUSE_DOWN , onSelect )

function onSelect(  event:MouseEvent ):void
{
        섬네일을 눌렀을 때 할일...
}


그러면 해당되는 이미지가 커다란 다른 View Pannel에서 크게 보여진다고 하자. 이 때 섬네일에서 필요한 최소의 정보는 커다란 사진의 경로를 View Pannel에게 알려주는 것이다.
function onSelect(  event:MouseEvent ):void
{
        dispatchEvent( 발생시킬 이벤트 )
}

그러나 어도비에서 만들어준 기본 이벤트에는 view Pannel에게 알려줄 사진경로의 정보를 포함시켜서 이벤트를 발생시킬 수 없다... 따라서 우리는 나름대로의 이벤트를 만들어서 그안에 정보를 담아 보내주도록 한다.
아래와 같이 Event를 상속받아서 기능을 추가한다. 추가되는 기능은 photoURL라는 파라미터를 만들어서 이벤트가 발생할 때 그 값을 받아 넘겨주도록 하는 것이다.
package
{
import flash.events.Event;
public class SelectEvent extends Event
 {
  public static const Select:String = "select";
  public var photoURL:String;
 
public function SelectEvent ( photoURL:String , type:String, bubbles:Boolean=false, cancelable:Boolean=false )
  {
   super( type, bubbles, cancelable );
   this.photoURL= photoURL;
  }
 
  override public function clone() : Event
  {
   return new UserEvent(this.photoURL, this.type, this.bubbles, this.cancelable);
  }
 }
}

위의 SelectEvent를 섬네일에서 dispatch 하면 아래와 같이 코딩한다.
private var bigSizeURL:String = "큰사진의 URL경로"
function onSelect(  event:MouseEvent ):void
{
        dispatchEvent( new SelectEvent(this.bigSizeURL,"select") )
       //SelectEvent에
photoURL의 값을 자신의 bigSizeURL로 설정
}

이처럼 섬네일에서만 알고있는 자신의 큰사진경로를 이벤트 발생시 이벤트의 파라미터로 등록하고 발송한다.
viewPannel에서는 사진을 불러들여야 하므로 다음과 같이 리스너가 등록되어있을 것이다.
thumbList.addEventListener.(SelectEvent.Select , onLoadPhoto)
function onLoadPhoto( event:SelectEvent ):void
{
      var photoUrl : String = event.photoURL;//SelectEvent에 포함되어있는 파라미터
      이미지를 photoUrl 에서 불러오는 코드....
}

위처럼 viewPannel에서는 섬네일 목록을 SelectEvent로 보고있다가 이벤트가 발생하면 섬네일에서 넘겨주는
url정보를 바탕으로 큰 사진의 이미지를 불러오도록 하는것이다.
중요한 것은 이벤트도 클래스이며 이를 상속받아 기능추가하거나 재정의가 가능하여 필요에 맞게 고쳐서 사용하면 되는 것이다.





Posted by 버터백통
Tip And Tech2008. 6. 7. 11:38

예전에 언어코드를 설계할 때 지금처럼 다양한 국가나 특수 문자 등의 설계가 포함되지 않았었다.
그래서 8비트의 아스키코드(ASCII : American Standard Code for Information Interchange)에서
확장된 16비트의 유니코드(Unicode)가 만들어지게 되었다.
하지만 아스키 방식은 문자당 1바이트를 사용하는데 반해 유니코드는 2바이트를 사용하게 되었다.
따라서 이러한 크기를 줄이기 위해 만들어진 것이 utf-8이다.
이 UTF-8은 아스키 코드의 영문이나 숫자등은 1바이트 형태로 표현하고 기타 국가언어는 2바이트 형태로
아스키와 유니코드를 혼용한 표현방식이 된 것이다.

Posted by 버터백통
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 버터백통