본문 바로가기

## 아이폰 ##

" object-c " Classess


Chapter 3. Classes

앞에서는 객체에 대한 일반적인 설명과 객체의 method들에 대해서 알아보았습니다. 순서가 뒤바뀐 면이 있군요. 이 장에서는 그런 객체를 어떻게 만들것인지, method는 어떻게 선언되는지에 대해서 알아보도록 하겠습니다. 즉 객체의 선언과 구현에 대해서 알아보는 것이 되겠습니다.

Objective-C 에서 객체를 정의하려면, 그 클래스를 정의하면 됩니다.

즉 C++에서 클래스를 정의하는 것과 개념적으로 완전히 동일합니다. 컴파일러는 실제로 각 클래스에 대해서 클래스 객체(class object)라는 것을 하나만 만듭니다. 이 클래스 객체는, 그 타입으로 만들어질 객체들을 어떻게 만들어야 할지에 대한 정보를 다 가지고 있으므로, factory object라고도 보통 불리곤합니다.

클래스 객체는 다시 말하자면 해당 클래스의 컴파일된 버젼입니다. 그 클래스 객체가 만드는 객체는 해당 클래스의 instance라고 합니다. 실제 돌아가는 프로그램에서 주된 역할을 하게 되는 객체들은 사실 이렇게 런타임시에 클래스 객체를 이용해서 만들어지는 instance들입니다.


NOTE : 이 부분은 Apple의 문서를 바로 번역한 것입니다. 이처럼 클래스와 객체(object), 그리고 instance를 쉽고도 명확하게 설명한 문서는 그리 많지 않은거 같습니다. C++에서는 항상 이 개념들을 명확하게 설명하지 않는 경향이있죠. 사실 그래도 별 문제는 없겠습니다. 결국 추상적인 클래스를 논리적으로 보느냐 런타임시의 실질적인 사물로 보느냐에 따른 용어이기 때문입니다. 컴파일러 제작자라면 이 개념을 명확히 구분할 필요가 있겠지만, 일반적으로는 그냥 섞어 사용해도 대개 의미 전달에는 크게 왜곡이 없으리라 봅니다. 물론 AT&T의 C++책에는 이 개념이 설명이 나와 있지만, 이렇게 쉽게 이해되게는 나와있지 않았었습니다. 이 점이 여러가지를 배워둘때 얻을 수 있는 장점이랄 수 있겠습니다.

클래스의 각 instance는 같은 method를 같습니다.

즉 같은 주물(鑄物)에서 만들어진 같은 instance 변수들을 가지게 됩니다. 이때 각 객체들은 그 instance 변수들을 자체적으로 내부에 가지게 되지만, method들은 서로 공유하게 됩니다.

클래스에 대한 코딩 스타일은, 전통적으로 그 이름을 대문자로 시작합니다. 예를 들자면 Rectangle 처럼 말입니다. 그리고 그 instance의 이름은 보통 소문자로 시작합니다. 이럴 경우에 myRect가 될 수 있겠습니다.


3.1 상속 ( Inheritance )

OOP언어인만큼 Objective-C 도 상속을 지원합니다. 즉 한 클래스를 만들때, 다른 클래스와 유사한 부분이 있다거나 같은 부류인데 좀 작은 개념이라고 생각될때, 다른 클래스의 instance 변수와 method를 그대로 받아서 새로운 클래스를 만들 수 있는 것입니다. 물론 이때, 다른 클래스로부터 받아들인 것을 그대로 쓰거나, 아니면 목적에 맞게 수정을 할 수있습니다.

상속을 하면 한개의 루트 클래스 밑에 여러개의 클래스들을 계층적인 형태로 연관지어 놓을 수 있습니다. 보통 Foundation 프레임워크를 이용해서 만들어지는 코드는, 루트로 NSObject를 위치시키게 됩니다. Root 클래스를 제외하면, 모든 클래스들은 그 상위로, 즉 루트 클래스에 좀더 가까운 방향으로 하나의 superclass를 가지게 됩니다. 이때 하나의 superclass라는 점에 주목하십시오. Objective-C는 다중상속을 지원하지 않습니다. 밑으로는 child class로 subclass를 가지게 됩니다.


용어를 정리해 봅시다.

 C++  Objective-C
 Parent class  superclass
 Child class  subclass


3.1.1 NSObject 클래스

NSObject는 root 클래스로써, superclass를 가지지 않습니다.

Cocoa에서 이 클래스는 모든 클래스의 root 클래스가 됩니다. 이 클래스로부터 상속을하면, runtime 시스템에서 지원을 받는 객체를 만들수 있습니다. 이러한 지원을 받지 않는 클래스를 만드려면 물론 NSObject로부터 상속을 하지 않아도 됩니다.

3.1.2 인스턴스 변수들을 상속하기

한 클래스를 상속하면 C++의 경우와 마찬가지로 superclass의 인스턴스 변수들도 모두 다 상속받게 됩니다. 그러므로 NSObject의 isa와 같은 인스턴스 변수는 NSObject를 상속한 모든 클래스에 자동으로 들어가게 됩니다.

3.1.3 method들을 상속하기

method 역시 인스턴스 변수들과 마찬가지의 방식으로 상속됩니다.

3.1.4 Method overriding

C++과 마찬가지로 Objective-C 도 method overriding이 됩니다. 즉 superclass로부터 상속받은 method를 뭔가 다른 식으로 바꾸고 싶다면, 같은 method 이름을 가진 method를 subclass에서 정의함으로써 superclass의 method대신에 invoke되게 할 수 있습니다.
물론 self와 super를 이용해서 overriding된 superclass의 method를 호출할 수도 있으니, 그때 그때 상황에 맞게 프로그래밍할 수 있습니다.
단 subclass는 superclass의 인스턴스 변수를 overriding할 수 없습니다. overriding하는 것은 method에 한합니다.


3.1.5 Abstract class

이것은 C++의 abstract와 같습니다. 즉 다른 subclass들로 하여금 특정 메소드와 인스턴스 변수들을 쓰게끔 하는 효과가 있습니다.
이런 예는 NSObject가 있겠습니다. 보통 NSObject의 subclass를 정의하는 프로그램에선, 그 subclass들을 사용을 하지 NSObject 클래스로 정의된 인스턴스를 바로 쓰지는 않습니다.

이 abstract 클래스는 abstract superclass라고도 종종 부릅니다.

3.2 클래스 type

클래스 정의는 어떤 종류의 객체에 대한 spec입니다. 그러므로 클래스는 어떤 데이터 타입을 정의하는 것입니다. 이때 그 타입은 그 클래스에 정의된 인스턴스 변수같은 데이터 구조뿐 아니라, 메소드와 같은 클래스의 “행위”에 의해서도 정의가 됩니다.
클래스 이름은 C에서 type specifier를 쓸 수있다고 한 곳에선 어디든지 쓸 수 있습니다.

즉 예를들면 sizeof 연산자 같은 경우,

int i = sizeof( Rectangle );

과 같은 식으로 클래스 이름을 sizeof의 인자로 전달할 수 있습니다.

3.2.1 Static Typing (정적 타이핑)

뒤의 chapter 7. Enabling Static Behaviors 에 나오겠지만, 클래스를 id와 같은 동적 타이핑이 아닌 static typing을 이용해서 정의할 수가 있습니다. 이건 마치 C++에서 클래스를 선언하듯이 하는 것입니다.

즉 다음과 같이 합니다.

Rectangle *myRect

또한 superclass 타입으로 타이핑도 가능합니다.

즉 다음과 같이 상속관계가 있다고 합시다.

Graphic   >>>   Rectangle

그렇다면 다음이 가능합니다.

Graphic *myRect;

물론 이렇게 선언만 하는 것이야 변수 이름을 마음대로 할 수 있으니 이 예만으론 별 의미가 없겠습니다.

하지만 여기서 말하고자 하는 것은 Graphic 타입으로 선언된 변수가 Rectangle 타입을 실지로 pointing할 수 있다는 것입니다.

3.2.2 Type Introspection

Type introspection이란 runtime시에 해당 인스턴스가 어떤 클래스의 인스턴스인지 등을 알아내는 것을 의미합니다.

좀더 일반적으로 말하자면 runtime시에 어떤 타입인지, 무엇을 할 수 있는지 등, 실행중에 변할 수 있는 부분을 알아낼 수 있는 메커니즘을 말합니다. NSObject에는 이런 용도로 isMemberOfClass와 같은 메소드가 정의되어 있습니다.

if( [anObject isMemberOfClass:someClass] )

라고 한다면 anObject라는 인스턴스가 someClass라는 클래스 타입인지 아닌지를 알 수 있습니다. 즉 return 값이 YES이면 someClass의 타입이란 것입니다.
좀더 포괄적인 것으로는 isKindOfClass가 있습니다.
if( [anObject isMemberOfClass:someClass] )

이것은 anObject의 수퍼클래스중 someClass가 있는가를 알아낼 수있게 합니다. 즉 someClass의 한 종류인지를 알 수있게 해준다는 것입니다. isMemberOfClass 경우는 직접적인 parent class, 다른 말로는 superclass의 형인지 아닌지를 알려주는데 반해, 이것은 직접적인 superclass가 아니어도 된다는 것입니다.
이외에도 주어진 객체가 특정 메시지에 반응하는지 아닌지를 알아내는 것등 introspection의 예는 많습니다.
3.3 클래스 객체 (Class Object)
클래스를 정의하려면 다음과 같은 정보가 필요하게 됩니다.

클래스를 정의하려면 다음과 같은 정보가 필요하게 됩니다.

'## 아이폰 ##' 카테고리의 다른 글

" object-c " Object Messaging  (0) 2010.10.21
" object-c " 객체  (0) 2010.10.21
" object-c " Language  (0) 2010.10.21
모바일웹 MP4.... 에혀... 이거  (0) 2010.08.13