oo::class — 모든 클래스의 클래스

oo::class — 모든 클래스의 클래스

TclOO 객체 시스템에서 모든 클래스는 oo::class의 인스턴스예요. 즉 클래스 자체가 객체라는 뜻이죠. 새 클래스를 만들거나, 그 클래스에서 인스턴스를 찍어내는 게 이 시스템의 핵심 동작입니다.

출처: oo::class manual page

본문

oo::class* method ?arg ...?

클래스 계층

oo::objectoo::class

클래스는 팩토리 객체(즉 클래스)에 저장된 패턴에 따라 다른 객체를 만들어 내는 객체입니다. 클래스의 인스턴스는 클래스의 팩토리 메서드 중 하나를 호출해 만드는데, 보통 명시적 이름을 줄 때는 create, 임의의 고유 이름을 자동으로 고를 때는 new를 써요.

oo::class 클래스는 모든 클래스의 클래스입니다. 모든 클래스는 이 클래스의 인스턴스이고, 따라서 이 클래스는 자기 자신의 인스턴스이기도 해요. 이 클래스는 oo::object의 서브클래스라서 모든 클래스는 객체이기도 합니다. 필요한 경우 oo::class를 서브클래싱해 추가 메타클래스(클래스들의 클래스)를 정의할 수 있어요. 단, oo::class 객체는 자기 자신의 new 메서드를 숨기므로, 새 클래스는 항상 create 메서드로 만들어야 합니다.

생성자

oo::class의 생성자는 선택 인자를 하나 받아요. 이 인자가 있으면 새로 만든 클래스의 이름과 함께 oo::define 명령으로 보내져, 생성 시점에 클래스를 편리하게 구성할 수 있습니다.

소멸자

oo::class는 명시적 소멸자를 정의하지 않습니다. 하지만 클래스가 파괴되면 그 모든 서브클래스와 인스턴스, 그리고 그 클래스가 mixin으로 들어간 모든 객체도 함께 파괴돼요.

내보내진 메서드

cls create name ?arg ...?

클래스 cls의 인스턴스를 name이라는 이름으로 생성합니다(완전히 정규화된 이름이 아니면 호출 문맥의 네임스페이스 안에서 해석돼요). 인자 *arg ...*를 생성자로 전달하고, (생성자가 성공 결과를 리턴하면) 생성된 객체의 완전히 정규화된 이름을 리턴합니다(생성자의 결과는 무시돼요). 생성자가 실패하면(즉 OK가 아닌 결과를 리턴하면) 객체는 파괴되고 오류 메시지가 이 메서드 호출의 결과가 됩니다.

cls new ?arg ...?

클래스 cls의 인스턴스를 새로운 고유 이름으로 생성합니다. 인자 *arg ...*를 생성자로 전달하고, (생성자가 성공하면) 생성된 객체의 정규화된 이름을 리턴합니다. 생성자가 실패하면 객체는 파괴되고 오류 메시지가 결과가 돼요.

이 메서드는 oo::class 객체 자체에서는 내보내지지 않으므로, 이 메서드로 클래스를 만들어서는 안 됩니다.

내보내지지 않은 메서드

cls createWithNamespace name nsName ?arg ...?*

클래스 cls의 인스턴스를 name이라는 이름으로 생성합니다. 인자 *arg ...*를 생성자로 전달하고, 성공하면 정규화된 객체 이름을 리턴합니다. 인스턴스 내부 네임스페이스의 이름은 nsName이 되며, 그 네임스페이스를 만들 수 없으면 오류예요. 생성자가 실패하면 객체는 파괴되고 오류 메시지가 결과가 됩니다.

예시

간단한 클래스 계층을 정의하고 그 인스턴스를 만들어 봅니다. 객체의 메서드를 호출한 뒤 계층을 파괴하고, 파괴가 전이적임을 보여줍니다.

oo::class create fruit {
    method eat {} {
        puts "yummy!"
    }
}
oo::class create banana {
    superclass fruit
    constructor {} {
        my variable peeled
        set peeled 0
    }
    method peel {} {
        my variable peeled
        set peeled 1
        puts "skin now off"
    }
    method edible? {} {
        my variable peeled
        return $peeled
    }
    method eat {} {
        if {![my edible?]} {
            my peel
        }
        next
    }
}
set b [banana new]
$b eat               → prints "skin now off" and "yummy!"
fruit destroy
$b eat               → error "unknown command"

더 알아보기

  • oo::define, oo::object — 클래스 구성과 객체 기본 동작
  • 키워드: class, metaclass, object