메타클라스

Metaclass

객체 지향 프로그래밍에서 메타클라스는 클래스를 예시하는 클래스다. 보통 계급이 특정 개체의 행동을 정의하듯이, 메타클라스는 특정 계급의 행동과 그 예시를 정의한다. 모든 객체 지향 프로그래밍 언어가 메타클라시를 지원하는 것은 아니다. 그러한 것들 중에서, 메타클라시가 계급행동의 어떤 주어진 측면을 무시할 수 있는 정도는 다양하다. 메타클라시는 1급 시민으로 하는 것으로 구현될 수 있는데, 이 경우 메타클라스는 단순히 클래스를 구성하는 물체일 뿐이다. 각 언어는 개체, 클래스, 메타클라스들이 상호 작용하는 방식을 지배하는 일련의 규칙인 고유의 메타 오브젝트 프로토콜을 가지고 있다.[1]

파이톤 예

Python에서는 빌트인 type 메타클라스야[2][3][4] 다음 간단한 Python 클래스를 고려하십시오.

계급 자동차:     반항하다 __init___(자아의, 만들다: 발을 동동 구르다, 본을 뜨다: 발을 동동 구르다, 연도: 인트로, 색을 칠하다: 발을 동동 구르다):         자아의.만들다 = 만들다         자아의.본을 뜨다 = 본을 뜨다         자아의.연도 = 연도         자아의.색을 칠하다 = 색을 칠하다      @property     반항하다 설명(자아의) -> 발을 동동 구르다:         """"이 차에 대한 설명을 반환한다."""         돌아오다 f"{자아의.색을 칠하다} {자아의.만들다} {자아의.본을 뜨다}" 

런타임에, Car 그 자체가 의 예다. type. 의 소스 코드 Car 위에 표시된 클래스는 크기(바이트)와 같은 세부 정보를 포함하지 않는다. Car 객체, 메모리의 이진 레이아웃, 할당 방법, 다음이 __init__ 방법은 매번 a로 자동 호출된다. Car 창조된 것 등등. 이 세부사항들은 단지 새로운 것만이 아니라 Car 객체가 생성되지만, 또한 매번 a의 모든 속성이 생성된다. Car 접속한다. 메타클라시가 없는 언어에서 이러한 세부사항은 언어 규격에 의해 정의되며 재정의될 수 없다. 파이톤에서는 메타클라스 - type - 다음 세부 정보 제어 Car의 행동 대신 다른 메타클라스(metaclass)를 사용함으로써 오버라이드할 수 있다. type.

위의 예에는 네 가지 속성에 대해 수행할 수 있는 몇 가지 중복 코드가 포함되어 있다. make, model, year, 그리고 color메타클라스를 사용하여 이러한 이중화의 일부를 제거할 수 있다. 파이톤에서 메타클라스는 가장 쉽게 정의된다. type.

계급 속성InitType(타자를 치다):     반항하다 __call__(자아의, *아그, **크워그):         """새 인스턴스를 만드십시오."""          # 먼저 정상적인 기본 방식으로 객체를 생성한다.         오비지 = 타자를 치다.__call__(자아의, *아그)          # 또한 새 개체에 속성을 설정하십시오.         을 위해 이름을 붙이다, 가치를 매기다  크워그.항목들():             세타트레(오비지, 이름을 붙이다, 가치를 매기다)          # 새 물건을 돌려준다.         돌아오다 오비지 

이 메타클라스는 객체 생성만 재정의한다. 클래스 및 오브젝트 동작의 다른 모든 측면은 여전히 에 의해 처리된다. type.

이제 수업은 Car 이 메타클라스를 사용하기 위해 다시 쓸 수 있다. Python 3에서 이것은 "키워드 인수"를 제공함으로써 수행되었다. metaclass 클래스 정의에 따라:

계급 자동차(반대하다, 메타클라스=속성InitType):     @property     반항하다 설명(자아의) -> 발을 동동 구르다:         """"이 차에 대한 설명을 반환한다."""         돌아오다 " ".합류하다(발을 동동 구르다(가치를 매기다) 을 위해 가치를 매기다  자아의._____.가치()) 

결과 객체 Car 평상시처럼 인스턴스화할 수 있지만 다음과 같은 키워드 인수를 얼마든지 포함할 수 있다.

신차 = 자동차(만들다='토요타', 본을 뜨다='프리스트스', 연도=2005, 색을 칠하다='녹색', 엔진='하이브리드') 

인 스몰토크-80

UML 다이어그램으로서의 Smalltalk-80 메타클라스 계층 구조
Smalltalk에서 클래스와 메타클라스 간의 상속 및 인스턴스 관계 다이어그램

스몰토크에서는 모든 것이 물건이다. 또한, Smalltalk는 클래스 기반의 시스템으로, 모든 물체는 그 물체의 구조(즉, 물체가 가지고 있는 인스턴스 변수)와 물체가 이해하는 메시지를 정의하는 클래스를 가지고 있다는 것을 의미한다. 이것은 함께 스몰토크의 클래스가 객체라는 것을 의미하며, 따라서 클래스는 클래스의 한 인스턴스(metaclas)가 되어야 한다는 것을 의미한다.

예를 들어, 자동차 물체는 c 수업의 한 예다. Car교대로, 학급은 Car 다시 하나의 대상이며, 그러한 예로서 의 메타클라스의 예로서 Car 불렀다 Car class. 메타클라스 이름에 빈칸을 기록하십시오. 메타클라스의 이름은 평가될 때 메타클라스 객체가 나타나는 스몰토크 표현식이다. 따라서 평가 Car class 에 대한 메타클라스 객체의 결과 Car 누구의 이름이냐 Car class (평가하여 이를 확인할 수 있다. Car class name 의 메타클라스의 이름을 반환하고 Car.)

인스턴스(instance) 방법이 실제로 클래스에 속하는 것처럼 클래스 메소드는 실제로 메타클라스에 속한다. 메시지가 개체로 전송될 때 2, 메서드에 대한 검색이 시작됨: Integer발견되지 않으면 슈퍼클래스 체인으로 올라가고, 발견 여부와 상관없이 오브젝트에서 멈춘다.

메시지를 보낼 때 Integer 그 방법에 대한 검색은 다음에서 시작된다. Integer class 그리고 슈퍼클래스 체인을 로 확장한다. Object class. 지금까지 메타클라스 상속 체인은 클래스 상속 체인의 상속 체인을 정확히 따르고 있다는 점에 유의하십시오. 하지만 메타클라스 사슬은 더 멀리 뻗어있다. Object class 의 하위 등급이다. Class모든 메타클라스들은 클래스의 하위 클래스들이다.

초기 스몰토크에는 메타클라스가 한 마리밖에 없었다. Class이는 모든 클래스가 가지고 있는 방법, 특히 새로운 객체를 만드는 방법 등이 동일하다는 것을 암시했다. new. 클래스에 고유한 방법과 인스턴스 변수(클래스 인스턴스 변수라고 하며 클래스 변수와 혼동해서는 안 됨)를 가지도록 하기 위해 각 클래스에 대해 Smalltalk-80을 도입했다. C 그들 자신의 메타클라스 C class이것은 각각의 메타클라스가 사실상 싱글톤급이라는 것을 의미한다.

메타클라시가 서로 다르게 행동할 필요가 없기 때문에, 모든 메타클라스는 오직 하나의 클래스라고 불리는 예일 뿐이다. Metaclass. 의 메타클라스 Metaclass 라고 불린다 Metaclass class 다시 한 번 계급의 예다. Metaclass.

Smalltalk-80에서는 모든 클래스(제외) Object)은 슈퍼클래스를 가지고 있다. 모든 메타클라스의 추상적인 슈퍼클래스는 Class그것은 계급의 일반성을 묘사한다.

메타클라시에 대한 슈퍼클래스 계층 구조는 클래스를 제외한 클래스에 대한 계층 구조와 유사하다. Object. 모든 메타클라스는 다음 등급의 하위 등급이다. Class따라서 다음과 같다.

  • Object class superclass == Class.

결합 쌍둥이처럼 계급과 전이가 함께 태어난다. Metaclass 인스턴스 변수가 있음 thisClass그것은 그것의 결합 계급을 가리킨다. 일반적인 Smalltalk 클래스 브라우저는 메타클라시를 별도의 클래스로 표시하지 않는다는 점에 유의하십시오. 대신 클래스 브라우저는 클래스를 메타클라스와 함께 동시에 편집할 수 있도록 허용한다.

메타클라스 계층 구조에서 클래스 이름은 동명의 개념과 쉽게 혼동된다. 예를 들어,

  • Object 모든 객체에 공통적인 방법을 제공하는 기본 클래스, "객체"는 정수 또는 위젯 또는 Car
  • Class 모든 계층에 공통적인 방법을 제공하는 메타클라시의 기반이다(메타클라스는 아니지만), "클래스"는 다음과 같은 것이다. Integer또는 Widget또는 Car
  • Metaclass 모든 메타클라스에게 공통적인 방법을 제공한다.

4개 학급은 새로운 학급을 기술할 수 있는 시설을 제공한다. 이들의 상속 계층(개체로부터)과 이들이 제공하는 주요 시설은 다음과 같다.

개체 - 클래스 액세스와 같이 모든 개체에 공통적인 기본 동작
동작 - 메서드를 컴파일하고 객체를 생성/실행하기 위한 최소 상태
ClassDescription(추상 클래스) - 클래스/변수 이름, 주석
클래스 - 유사하고, 보다 포괄적이며, 슈퍼클래스와 같은 시설
메타클라스 - 클래스 변수, 인스턴스 생성 메시지 초기화

인 루비

루비는 스몰토크-80 개념의 메타클라스(metaclasses)를 정화하고, 아이겐클래스를 도입하여 그 개념을 제거한다. Metaclass class of map, class-of-mapsing. 변경사항은 다음과 같이 도식화할 수 있다.[5]

스몰토크-80
암묵적
메타클라시스
터미널
물건들
루비
아이겐클래스
아이겐클래스목

고유종
터미널
물건들
아이겐클래스
말단 물체

특히 스몰토크의 암묵적인 메타클라스들과 루비의 고유 계급들 사이의 일치점을 주목하라. 루비 아이겐클래스 모델은 암묵적 메타클라스 개념을 완전히 균일하게 만든다: 모든 물체 x는 x아이겐클래스라고 불리는 고유한 메타 객체를 가지고 있는데, 이것은 x보다 한 메타레벨이다. "높은 순서" 고유 분류는 대개 순전히 개념적으로 존재한다. – 그들은 어떤 방법도 포함하지 않고 대부분의 루비 프로그램에 어떤 (다른) 데이터도 저장하지 않는다.[6]

다음 도표는 스몰토크-80과 루비의 샘플 코어 구조를 비교해서 보여준다.[7] 두 언어 모두에서 구조는 원형 객체(즉, 파란색 또는 녹색 링크의 조합으로 형성된 사이클로 나타나는 객체)를 포함하는 내장 부품과 4개의 명시적 객체(클래스)를 가진 사용자 부품으로 구성된다. A , 그리고 B 및 터미널 객체 u , 그리고 v. 녹색 링크는 상속의 자식→부모 관계(암묵적인 위쪽 방향)를 나타내고, 파란색 링크는 인스턴스화의 보완적 멤버→컨테이너 관계를 나타낸다(x에서 메서드를 호출할 때 메서드 룩업의 시작점이 되는 x의 최소 실제 컨테이너에 대한 파란색 링크). 회색 노드는 고유 클래스를 표시한다(Smalltalk-80의 경우 암시적 메타클라스).

스몰토크-80 루비
Implicit metaclasses in Smalltalk-80 - A sample structure Eigenclasses in Ruby - A sample structure

오른쪽의 도표는 루비의 고유계급에 대한 게으른 평가 그림도 제공한다.v 객체에 싱글톤 방법을 추가하는 결과로 고유 클래스를 평가(평가)할 수 있다. v.

루비의 내성법에 따르면 class, 모든 클래스의 클래스 (그리고 모든 고유 클래스의 클래스)는 항상 Class 계급(에 의해 표시됨) c 도해로 Class, 그리고 Struct 클래스가 인스턴스로 있는 유일한 클래스.[8][disputed ] 하위 분류: Class 허용되지 않는다. 메타클라시에 대한 표준 정의에 따라 우리는 다음과 같이 결론을 내릴 수 있다. Class , 그리고 Struct 루비에 있는 유일한 메타클라스야 이것은 스몰토크-80에서는 모든 계급이 그들만의 메타클라스를 가지고 있기 때문에 루비와 스몰토크 사이의 통신에 모순되는 것처럼 보인다. 그 불일치는 두 사람의 의견 차이에서 비롯된다. class Ruby와 Smalltalk의 자기성찰법. 지도가 x x x인 동안.class 터미널 객체와 일치하며, 클래스에 대한 제한에 차이가 있다. 위에서 언급한 바와 같이, 수업은 x, 루비표현 x.class 에 끊임없이 평가하다. Class. 스몰토크-80에서, 만약 x 그 표현보다 계급이다. x class 루비족에 해당한다. x.singleton_class - 의 고유 등급에 따라 평가되는 항목 x.

In Objective-C

목표-C에서 클래스와 메타클라스 간의 상속 및 인스턴스 관계를 나타내는 다이어그램. Object-C에는 여러 루트 클래스가 있으며 각 루트 클래스는 별도의 계층 구조를 가질 수 있다는 점에 유의하십시오. 이 다이어그램은 루트 클래스 NCObject의 계층만 보여준다. 서로 다른 루트 클래스는 유사한 계층 구조를 가질 수 있다.

목표-C의 메타클래스는 작은말-80의 메타클래스와 거의 똑같다. 목표-C가 작은말로부터 많은 돈을 빌리기 때문에 놀랄 일은 아니다. Smalltalk와 마찬가지로 Object-C에서 인스턴스(instance) 변수와 방법은 객체의 클래스에 의해 정의된다. 클래스는 물체여서 메타클라스의 한 예다.

Smalltalk와 마찬가지로, Object-C에서 클래스 메소드는 클래스 객체에서 호출되는 메소드일 뿐이므로 클래스의 클래스 메소드는 메타클라스에서 인스턴스 메소드로 정의되어야 한다. 등급마다 등급 방법이 다를 수 있기 때문에 각 등급마다 별도의 메타클라스가 있어야 한다. 클래스 및 메타클래스는 항상 쌍으로 생성되며, 런타임에는 기능이 있음 objc_allocateClassPair() , 그리고 objc_registerClassPair() 각각 클래스-메타클라스 쌍을 만들고 등록한다.

메타클라시에 대한 이름은 없지만 일반 유형으로 클래스 객체에 대한 포인터를 참조할 수 있다. Class (타입에 따라 다름) id 모든 물체에 대한 포인터로 사용됨).

클래스 방법은 스몰토크와 같이 상속을 통해 상속되기 때문에 메타클라시스는 루트 클래스를 제외하고 클래스와 유사한 상속 방식(예: 클래스 A의 부모 클래스가 클래스 B인 경우, A의 부모 클래스가 B의 메타클라스인 경우)을 따라야 한다.

스몰토크와 달리 루트 클래스의 메타클라스는 루트 클래스에서 상속된다(보통 NSObject 코코아 프레임워크 사용) 자체 이렇게 하면 모든 클래스 개체가 궁극적으로 루트 클래스의 인스턴스(instance)가 됨을 보장하므로, 클래스 개체 자체에서 루트 클래스의 인스턴스(instance) 방법, 대개 객체에 유용한 유틸리티 방법을 사용할 수 있다.

메타클라스 개체는 서로 다르게 동작하지 않기 때문에(메타클라스에는 클래스 메서드를 추가할 수 없으므로 메타클라스 개체는 모두 동일한 메서드를 가지고 있다), 모두 같은 클래스의 인스턴스, 즉 루트 클래스의 메타클라스(스몰토크와는 달리)이다. 그러므로 루트 클래스의 메타클라스는 그 자체의 한 예다. 그 이유는 모든 메타클라시가 루트 클래스에서 상속받기 때문에 루트 클래스의 클래스 방법을 상속받아야 하기 때문이다.[9]

언어 및 도구 지원

다음은 메타클라시를 지원하는 대표적인 프로그래밍 언어들이다.

메타클라시를 지원하는 일부 덜 널리 사용되는 언어는 OpenJava, OpenC++, OpenAda, CorbaScript, ObjVlisp, Object-Z, MODE-K, XOTCL, MELDC 등이다. 이러한 언어들 중 몇몇은 1990년대 초반부터 시작되었고 학문적인 흥미가 있다.[11]

프롤로그의 객체지향 확장인 로그토크도 메타클라시를 지원한다.

RDF(Resource Description Framework)와 UML(Unified Modeling Language)은 모두 메타클라시를 지원한다.

참고 항목

참조

  1. ^ Ira R. Forman and Scott Danforth (1999). Putting Metaclasses to Work. ISBN 0-201-43305-2.
  2. ^ Python의 IBM Metaclas 프로그래밍, 파트 1 Wayback Machine에 2008-09-03 보관, 2 3
  3. ^ Artima 포럼: Python 3.0의 메타클라스(2의 1부)(2의 2부)
  4. ^ David Mertz. "A Primer on Python Metaclass Programming". ONLamp. Archived from the original on April 30, 2003. Retrieved June 28, 2006.
  5. ^ "The Ruby Object Model: Comparison with Smalltalk-80".
  6. ^ Paolo Perrotta (2010). Metaprogramming Ruby. Pragmatic Bookshelf. ISBN 978-1-934356-47-0.
  7. ^ "Object Membership: The Core Structure of Object Technology".
  8. ^ "Struct". Ruby Doc. Retrieved 1 May 2015.
  9. ^ 사랑이 담긴 코코아: 목표-C에서 메타클래스란 무엇인가?
  10. ^ Herb Sutter. "Metaclasses" (PDF).
  11. ^ "An implementation of mixins in Java using metaclasses" (PDF). Archived from the original (PDF) on 2007-10-16. Retrieved 2007-11-27.