SqueakByExample:5.4

From 흡혈양파의 번역工房
Revision as of 04:59, 30 August 2012 by Onionmixer (talk | contribs)
Jump to navigation Jump to search

모든 클래스는 수퍼클래스(superclass)를 갖습니다.

스몰토크에서 각각의 클래스는 단일 수퍼클래스로부터, 클래스의 동작 그리고 구조의 설명을 상속합니다. 이 의미는 스몰토크는 단일 상속을 갖고 있다는 것입니다.


SmallInteger superclass ⇒ Integer
Integer superclass ⇒ Number
Number superclass ⇒ Magnitude
Magnitude superclass ⇒ Object
Object superclass ⇒ ProtoObject
ProtoObject superclass ⇒ nil


전통적으로, 스몰토크 상속 계층도(the smalltalk inheritance hierarchy)의 뿌리(root)는 클래스 오브젝트입니다. (모든 것이 오브젝트이기 때문에). 스퀵에서, 뿌리(root)는 실제로 ProtoObject라 지칭되는 클래스이지만, 평상시에 여러분이 이 클래스에 주의를 기울일 필요는 없을 것입니다. ProtoObject는 모든 오브젝트가 반드시 가져야 할 메시지의 최소 세트를 인캡슐레이션 합니다. 그럼에도 불구하고 대부분의 클래스는 오브젝트로부터 상속을 받으며, 이것은 거의 모든 오브젝트가 반드시 이해하고 응답해야 할 많은 부가적인 메시지를 정의합니다. 여러분이 다르게 작업을 해야 할 이유가 분명하지 않다면, 어플리케이션 클래스를 만드실 때, 오브젝트 또는 그것의 서브 클래스들 중 하나를 하위분류 하셔야 합니다.


Squeak comment.png새로운 클래스는 보통 메시지 subclass:instanceVariableNames:... 을 보냄으로써 만들어집니다. 클래스를 만들기 위한 몇 가지 다른 메서드가 있습니다. 그 메서드들이 무엇인지 보기 위해 프로토콜 Kernel-Classes ▷ Class ▷ subclass 을 보십시오.


비록 스퀵이 다중 상속을 제공하지 않음에도 불구하고, 버전 3.9 이후로, 관련되지 않은 클래스들의 기능들을 공유하기 위한 traits라 지칭되는 메커니즘을 포함시켰습니다. Traits는 상속과 관련되지 않은 다중 클래스들을 사용하여 재사용할 수 있는 메서드들의 컬랙션입니다. Traits를 사용은 코드를 복제하지 않고, 다양한 클래스들 사이의 코드공유를 가능케 합니다.


Abstract(추상)메서드와 abstact(추상) 클래스

Abstract(추상) 클래스는 예를 들어 설명되기 보다, 하위분류 되야 할 존재하는 클래스입니다. Abstact(추상) 클래스는 그것이 사용하는 모든 메서드를 정의하지 않는다는 면에서 일반적으로 완전한 클래스가 아닙니다.("missing" 메서드-다른 메서드들을 가늠해 보듯이) 그러나 이 클래스들은 그 자체가 정의되지 않은-abstract(추상) 메서드로 지칭됩니다.

스몰토크는 메서드 또는 클래스가 추상(abstract)으로 지정하는 목적에 쓰이는 어떤 전용 구문도 갖고 있습니다. 관례적으로, 추상(abstract) 메서드의 본체(Body)는 표현식 self subclassResponsibility로 구성되어 있습니다. 이것은 "마커 메서드(marker method)" 로 알려져 있으며, 서브클래스가 메서드의 실체적인 버전을 정의할 책임을 갖고 있다는 것을 가리킵니다. Self subclassResponsibility 메서드는 항상 재지정(overridden)되므로, 절대로 실행하면 안됩니다. 만약 여러분이 재지정 하는 것을 잊어버리고, 그 메서드를 실행하면, 예외가 적용될 것입니다.

클래스는 만약 그 클래스의 메서드들 중의 하나가 추상적이면, 추상 클래스(abstract class)로 분류됩니다. 실제로 어떤 것도, 여러분을 추상 클래스의 인스턴스를 만드는 작업을 방해할 수 없으며, 모든 것은 추상메서드를 부를 때까지 작동될 것입니다.

Example :클래스 Magnitude(매그니튜드)

Magnitude(매그니튜드)는 서로서로를 비교할 수 있는 오브젝트를 정의하기 위해 우리를 돕는 추상 클래스(abstract class)입니다. Magnitude 의 서브클래스는 반드시 메서드 <, = 와 hash를 실행할 수 있어야만 합니다. 이러한 메시지들을 사용하여, Magnitude 는 as >, >=, <=, max:, min: between:, :와 같은 다른 메서드들과 또 다른 메서드들을 오브젝트와 비교하기 위해 정의합니다. 메서드 <은 추상메서드 이며 메서드 5.7에서 보이는 것처럼 정의합니다.


메서드5.7:Magnitude»<

Magnitude»< aMagnitude
  "Answer whether the receiver is less than the argument."
  self subclassResponsibility


반대로, 메서드>=는 실체적이며, <를 환산하여 정의됩니다.


메서드 5.8: Magnitude»>=

>= aMagnitude
  "Answer whether the receiver is greater than or equal to the argument."
  (self < aMagnitude) not


이 사항은 동일하게, 다른 비교 메서드에서도 적용됩니다.

Character는 Magnitude의 서브클래스입니다. 이것은 <의 그 자체 버번으로 subclassResponsibility 메서드를 재지정(override)합니다 (메서드 5.9를 보세요). Character는 또한 메서드 =와 harsh를 정의하며, 메서드 >=, <=,~ = 와 다른 것들인 Magnitude로부터 상속받습니다.


메서드 5.9: Character»<

Character»< aCharacter
  "Answer true if the receiver's value < aCharacter's value."
  self asciiValue < aCharacter asciiValue


Traits

Trait는 상속할 필요 없이 클래스의 동작에 포함될 수 있는 메서드의 컬렉션 입니다. 이것은 클래스가 고유한 수퍼클래스(superclass)를 쉽게 갖도록 만들면서도, 여전히 관련되지 않은 클래스들과 유용한 메서드를 공유합니다.

새로운 trait을 정의하려면, 단순히 클래스 trait에 대한 메시지로 서브클레스 생성 탬플릿(the subclass creation template)를 교체합니다.


클래스 5.10: 새로운 trait을 정의하기

Trait named: #TAuthor
  uses: { }
  category: 'SBE--Quinto'


여기서 우리는 카테고리 SBE-Quinto에서 trait TAuthor를 정의할 것입니다. 이 trait은 현존하는 다른 traits을 사용하지 않습니다. 일반적으로, 우리는 키워드 인수 사용의 일부로 사용할 다른 traits의 trait 작성 표현식(a trait composition expression)을 지정할 수 있습니다. 여기서는 단지, 빈 array를 제공할 것입니다.

Traits는 메서드를 포함할 수 있지만, 인스턴스 변수는 포함시키지 않습니다. 우리가 계층도에서 클래스들이 발생되는 독립된 위치에 소재한, 다양한 클래스에 author 메서드를 더할 수 있을 것이라고 가정하면. 다음과 같이 작업이 수행될 것입니다:


메서드 5.11: Author 메서드

TAuthor»author
  "Returns author initials"
   'on' "oscar nierstrasz"


이제 우리는, 2장에서 우리가 정의한 SBEGame 클래스의 인스턴스를 위해 이미 그 자체의 superclass를 갖고 있는 클래스에서 이 trait을 사용할 수 있습니다. 우리는 단지 TAuthor가 반드시 사용되어야 한다고 지정하는 키워드 인수 uses:를 포함하기 위해 SBEGame을 위한 클래스 생성 탬플릿(the class creation template를 수정하면 됩니다.


클래스 5.12: trait 사용하기

BorderedMorph subclass: #SBEGame
  uses: TAuthor
  instanceVariableNames: 'cells'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'SBE--Quinto'


만약 우리가 SBEGame을 초기화하였다면, 이것은 기대했던 것처럼 author 메시지에 응답할 것입니다.


SBEGame new author  'on'


Trait 작성 표현식(composition expressions)는 + 연산자를 사용하여 다중 traits을 결합할 수 있을 것입니다. 충돌이 생기는 경우(예를 들면, 다중 traits이 동일한 이름으로 메서드들을 정의할 경우), 여러분은 이 메서드들을 (-으로) 또는 클래스에서 정의하거나 여러분이 정의하는 trait으로써, 이 메서드들을 명확하게 제거하여 충돌을 해결할 수 있습니다. 또한 새로운 이름을 제공하여, alias 메서드에(@과 함께) 적용하는 것도 가능합니다.

Traits는 시스템 커널(the system kernel)에서 사용됩니다. 하나의 좋은 예는 클래스 Behavior입니다.


클래스 5.13: traits을 사용하여 정의된 동작

Object subclass: #Behavior
  uses: TPureBehavior @ {#basicAddTraitSelector:withMethod:-->
    #addTraitSelector:withMethod:}
  instanceVariableNames: 'superclass methodDict format'
  classVariableNames: 'ObsoleteSubclasses'
  poolDictionaries: ''
  category: 'Kernel--Classes'


여기서 우리는 basicAddTraitSelector:withMethod: 에 에일리어스된(alias, 하나의 프로그램에서 동일한 기억 장소를 참조하는 변수에 둘 이상의 이름이 붙은 것:역주) trait TPureBehavior에서 정의된 메서드 addTraitSelector:withMethod:를 보게 됩니다. Traits을 위한 지원은 현재 브라우저에 추가되고 있는 중입니다.

Notes