Study/iPhone

Objective-C - 1.클래스에 관하여...

빨간당무 2010. 5. 6. 22:58

/*
■ 클래스에 관하여...
클래스는 설계도 이고, 인스턴스는 설계도를 바탕으로 만든 물건이라고 보면 된다.

예를 들면 붕어빵을 굽기 위해 사용되는 붕어빵틀은 클래스이고
붕어빵틀을 이용해 만들어진 붕어빵은 인스턴스이다.

인스턴스 변수는 각 인스턴스가 갖는 고유의 상태(값)이고,
인스턴스 메서드는 각 인스턴스가 갖는 기능(행동)이다.
클래스 메서드는 클래스가 갖는 기능이다.

예를 들어 [자동차]라는 클래스가 있고 인스턴스 변수로 [색상]이 있다고 할 때,
[자동차]클래스의 인스턴스인 [빨간색차]와 [파란색차]를 생성한 경우,
[빨간색차]의 인스턴스 변수 [색상]의 값은 [빨간색]이고,
[파란색차]의 인스턴스 변수 [색상]의 값은 [파란색]이다.

또한 각 인스턴스 메서드로 각각 다르게 수행되는 [시동걸기]가 있다.
그럼 클래스 메서드는 무엇인가? 이것은 클래스 자체로 사용되는 메서드로
[자동차생산]이 있다고 생각하면 된다.

■ 클래스를 새로 정의하는 경우 (정의)
@interface ClassName : NSObjectOrParentClass
{
    memberDeclarations;    // 인스턴스 변수들
}
-InstanceMethodDeclarations;        // 인스턴스 메서드 ('-'로 시작시)
+ClassMethodDeclarations;           // 클래스 메서드  ('+'로 시작시)
@end

예를 들면
@interface 자동차 : NSObject
{
    string 색상;
}
-(void) 시동걸기;           // 앞에 -로 시작하면 인스턴스 메서드
-(string) 차색상얻기;
-(void) 차색상지정: (string)차색상;
+(void) 자동차생산;         // 앞에 +로 시작하면 클래스 메서드
@end

라고 보면 된다. 얼핏 설명이 부족해서 이해가 안될 것을 우려해 추가로 설명하자면
인스턴스 메서드는 인스턴스 별로 호출하였을 때 인스턴스 내부 상태에 따라
동일하게 또는 다르게 수행되는데에 반해,
클래스 메서드는 클래스 자체에서 호출하기 때문에 동일하게 된다. (또한 호출방법도 다르다)
메서드에 대해 예를 들어 추가 설명을 하자면

-(void) 차색상지정: (string)차색상;

에서 제일 처음 [-]는 메서드형이고(- or +)
다음으로 [(void)]는 반환값이고(void or 다른자료형)
다음으로 [차색상지정]은 메소드 이름이고
다음으로 [:]은 이후 인수가 있다는 것이고
다음으로 [(string)]은 인수형태(자료형) 이고
다음으로 [차색상]은 인수이름이다.
여기서는 인수가 하나 혹은 없는 경우만 나열했는데 차후 인수가 여러개인 것에 대해서도 설명한다.

■ 클래스와 인스턴스에 메서드를 적용할 때의 문법(syntax)
[Instance method];   // 인스턴스 메서드 호출시
[Class method];      // 클래스 메서드 호출시

// 인스턴스 메서드 호출
[빨간색차 차색상지정:빨간색];
[파란색차 차색상지정:파란색];   // [차색상지정]하는 역할은 갖지만 인수가 다르다. 

[빨간색차 시동걸기];
[파란색차 시동걸기];   // 이때는 [시동걸기]의 기능은 동일하다. (물론 설계에 따라 다르다.)

[빨간색차 차색상얻기];
[파란색차 차색상얻기]; // 이때는 인스턴스 변수를 가져와서 보여주기 때문에 다른 값이 나온다.

// 클래스 메서드 호출
[자동차 자동차생산];

이게 좀더 이해하기 직관적인것 같지만 이해하지 못하겠다면 일단 넘어가도 좋다.
일반적으로 클래스 설계시에는 인스턴스 메서드 용으로 대부분 설계한다는 것만 생각하면 된다.

■ 클래스를 새로 정의하는 경우 (구현)
앞서 [자동차] 클래스를 정의했지만 실제 기능을 구현하지는 않았다.
위 예를 적용하여 예를 들면
@implementation 자동차
-(void) 시동걸기
{
    NSLog("자동차의 시동을 걸었다.");  // 어떠한 역할을 했다고 출력함
}
-(string) 차색상얻기;
{
    return 색상;      // 인스턴스 변수인 [색상] 값을 반환함
}
-(void) 차색상지정: (string)차색상;
{
    색상 = 차색상;    // 인수로 받은 [차색상]을 인스턴스 변수 [색상]에 입력한다.
}
+(void) 자동차생산;
{
    NSLog("자동차를 생산한다.");     // 어떠한 역할을 했다고 출력함
}
@end

직관적으로 이해했으리라 생각되지만(!) 굳이 설명하자면... 설명은 생략함... (급 채력 상실...)

추가로 인스턴스 변수의 값을 가져오는 특별한 메서드를 이야기 하자면...

예를 들어 클래스에 인스턴스 변수 num이 있고 이 인스턴스 변수 num을 가져오기 위해
인스턴스 메서드 num을 만들어서 사용할 수 있다. (인스턴스 변수 num과 인스턴스 메서드 num이 이름이 같다!!!)
코드로 보면

@interface ExampleClass : NSObject
{
    int num;
}
@end
-(int)num;
-(void) setnum: (in) n;

@implementation ExampleClass
-(int)num       // 여기가 인스턴스 메소드에서 인스턴스 변수를 반환하도록 되어 있다. // 일반적으로 게터(getter)라고 함
{
    return num;            
}
-(void) setnum: (in) n;     // 일반적으로 세터(setter)라고 함
@end

일반적으로 인스턴스 변수와 인스턴스 메서드는 이름이 중복되면 안되지만, Objective-C에서는 전혀 문제가 되지 않으며,
오히려 널리 쓰이는 방법으로 애플에서는 이러한 형태의 메서드 이름을 사용하는 것을 권장한다고 한다.

■ 객체를 이용한 인스턴스 생성, 할당, 초기화 과정
클래스를 통해 인스턴스를 생성하고 이용하고자 한다면 다음과 같은 절차를 거쳐야한다.
// 인스턴스 생성 : [자동차] 클래스를 이용하여 [빨간색차] 인스턴스를 생성
자동차 *빨간색차;
// 인스턴스 할당 : [빨간색차] 인스턴스에 [자동차] 클래스 내용을 메모리에 담을 수 있도록 메모리 공간을 할당
빨간색차 = [자동차 alloc];
// 인스턴스 초기화 : [빨간색차] 인스턴스의 초기화을 진행
빨간색차 = [빨간색차 init];

또는
자동차 *빨간색차 = [[자동차 alloc] init];  // 앞서 3단게를 한줄로 축약

또는
자동차 *빨간색차 = [자동차 new];           // 앞서 3단계를 한줄로 축약 (new은 alloc, init을 연속해서 작업해줌)

■ 앞서 배운 내용으로 간단하게 프로그램을 구현해 본다.
*/

#import <Foundation/Foundation.h>

// 클래스 정의(definition)
@interface ExampleClass : NSObject      // 클래스 정의, NSObject 클래스를 상속함
{
    int num;              // 인스턴스 변수
}
-(int) num;               // 인스턴스 메서드 (-로 시작함)
-(void) setNum: (int) n;
@end                                   // 클래스 정의 종료

// 클래스 구현 (implement)
@implementation ExampleClass           // 클래스 구현
-(int) num
{
    return num;
}
-(void) setNum: (int) n
{
    num = n;
}
@end                                   // 클래스 구현 종료

// 프로그램 실행 (program)
int main(int argc, char argv[])        // 프로그램 진입점(시작 위치)
{
    NSAutoreleasePool *pool;              // 인스턴스 생성
    pool = [NSAutoreleasePool alloc];     // 인스턴스 할당
    pool = [pool init];                   // 인스턴스 초기화
    // or (한줄로 쓰면)
    //NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    // or (한줄로 쓰면)
    //NSAutoreleasePool *pool = [NSAutoreleasePool new];
    // ref ⇒ new = alloc + init
   
    ExampleClass *ec = [[ExampleClass alloc] init];     // 인스턴스 생성, 할당, 초기화
   
    [ec setNum:29];  // 값 지정하기
   
    int result;
    result = [ec num];  // 값 가져오기
   
    NSLog(@"result : %d", result);
   
    [pool drain];
    system("PAUSE");
}

'Study > iPhone' 카테고리의 다른 글

[iOS] UITextView에 라운드 테두리 효과 적용  (4) 2011.06.19
iPhone 개발자 등록완료  (0) 2010.04.10