이제 끝으로 Rectangle를 상속받는 PositionedRectangle 클래스를 정의해 보겠습니다. Rectangle 클래스는 단순히 가로와 세로 크기값만을 가지고 있습니다. 여기에 위치값까지 갖도록 한 클래스가 바로 PositionedRectangle 클래스입니다.
var PositionedRectangle = Class({ name: "PositionedRectangle", extend: Rectangle, construct: function(x,y,w,h) { this.superclass(w, h); this._x = x; this._y = y; }, methods: { draw: function() { alert("draw PositionedRectangle"); }, getPosition: function() { return new Coordinate(this._x, this._y); } }, requires: [aShape], statics: { isSame: function(a, b) { return a._x == b._x && a._y == b._y && a._width == b._width && a._height == b._height; } } });
중요한 부분은 바로 3번 코드로 상속받고자 하는 클래스를 지정하는 extend입니다. 바로 이 extend로 지정된 클래스의 모든 속성값을 상속받게 되는데 이 PositionedRectangle 클래스는 Rectangle 클래스의 모든 속성(변수와 매서드)를 상속받게 됩니다.
추가로 18번 코드는 정적 속성(변수와 매서드)를 정의하는 방법입니다. 이는 C++과 자바와 같은 언어에서 클래스 차원에서 제공하는 바로 그 기능입니다.
이제 이렇게 정의한 클래스들을 직접 사용하는 예를 보이면 다음과 같습니다.
var c = new Circle(100, 100, 30); var r = new PositionedRectangle(10, 10, 100, 100) alert(r instanceof Rectangle); alert(r instanceof PositionedRectangle); alert(r instanceof Object); alert(r instanceof Circle); c.draw(); r.draw(); alert(c.getCenter().toString()); alert(PositionedRectangle.isSame(r, r));
1번과 2번 코드는 클래스를 통해 객체를 생성하고 있습니다. 그리고 4~7번 코드에서 각 객체가 어떤 클래스의 인스턴스인지를 검사하고 있습니다. 결과값은 순서대로 true, true, true, false입니다. 그리고 9~10번 코드는 draw 함수를 호출하고 있습니다. 마친가지로 12번 ~ 13번 코드는 정의한 매서드를 사용하고 있습니다.
이상으로 클래스 정의 API에 대한 내용을 마무리합니다. 중요한 것은 자바스크립트는 결코 완벽한 클래스 정의를 제공해주지 못합니다. 이는 언어적 한계입니다. 이러한 한계를 해결한 버전이 자바스크립트 2.0입니다. 자바스크립트 2.0이 나오기 전까지는 이러한 클래스 정의 API를 개발자가 직접 만들고 이해하여 사용해야 하며 스스로에 대한 약속을 정해 반드시 준수해야 합니다. 이러한 약속은 private 변수의 경우 변수명 앞에 밑줄(_)을 넣는 등에 대한 것입니다. 가장 중요한 것은 문서화 입니다. 자바스크립트는 매우 유연한 언어이므로 문서화를 통해 약속을 분명히 기술하여 지킬 수 있도록 해야합니다.