인스턴스 변수의 공개 범위
일반적으로 클래스는 구조체와 역할이 다르기 때문에 새로운 데이터 형식으로만 클래스가 존재해야 하는 것은 아닙니다. 그러나 RGB 형식의 색을 표현하기 위한 클래스와 좌표와 크기를 나타내는 클래스라면 메시지로 값을 얻는 등의 처리는 다소 중복적이므로 직접 인스턴스 변수와 상호 작용할 수 있는 편이 좋다고 생각하는 개발자도 있을 것입니다.
원칙적으로, 클래스의 인스턴스 변수는 외부에서 액세스할 수 없어야 하며, 기본적으로 외부에서 인스턴스 변수에 접근하는 것은 불가능합니다. 인스턴스 변수를 클래스의 외부 메서드에서 접근하게 되면 변수에 저장되는 값의 무결성을 유지할 수 없게 되기 때문입니다. 외부에서 인스턴스 변수에 액세스하려면 먼저 인스턴스 변수의 가시범위를 명확하게 이해 해야 합니다.
인스턴스 변수의 가시범위는 어디에서나 액세스할 수 있음을 나타내는 public, 비공개를 나타내는 private, 서브 클래스에서만 액세스할 수 있는 protected로 나뉩니다. public은 클래스 외부와 서브 클래스를 포함하여 어떤 위치에서나 인스턴스를 통해 액세스할 수 있는 변수를 나타냅니다. private는 반대로 인스턴스 변수를 선언한 클래스의 메서드에서만 액세스할 수 있는 변수입니다. 그리고, protected 변수는 선언한 클래스와 해당 클래스의 하위 클래스에서만 액세스할 수 있는 변수를 나타냅니다.
인스턴스 변수에 가시범위를 지정하려면 컴파일러 지시자인 @public @private, @protected 중 하나를 인스턴스 변수 선언 부분 사이에 추가합니다. 이 컴파일러 지시어를 사용하면, 그 이후에 선언된 인스턴스 변수는 모두 지정된 가시범위로 설정됩니다. 가시범위가 지정되지 않은 경우, 인스턴스 변수는 기본적으로 protected로 설정됩니다.
@interface A : Object
{
int z; //protected
@public int a; //public
@protected int b; //protected
@private int c; //private
int d; //private
}
@end
이와 같이 가시범위를 지정하면 선언된 인스턴스 변수는 해당 가시범위를 가지게 됩니다. 가시범위 지정 컴파일러 지시어는 사용 횟수와 순서에 제한이 없습니다.
public 지시어로 공개되는 변수를 클래스 외부에서 인스턴스를 통해서 액세스하려면 클래스 형의 포인터 변수에서 -> 연산자를 사용하여 인스턴스 변수에 액세스 합니다. 이것은 구조체에 대한 포인터를 사용하여 멤버 변수에 액세스하는 방법과 동일 합니다. 인스턴스 변수에 대한 액세스는 컴파일 타임에서는 형식 검사가 수행되기 때문에 id 변수에 접근하는 것은 불가능합니다.
#import <stdio.h>
#import <objc/Object.h>
@interface A : Object
{
@public
int a;
@protected
int b;
@private
int c;
}
- (id) initWithA : (int) a int : (int) b int : (int) c;
- (void) WriteA;
@end
@interface B : A
- (void) WriteB;
@end
@implementation A
- (id) initWithA : (int) a int : (int) b int : (int) c
{
self->a = a;
self->b = b;
self->c = c;
return self;
}
- (void) WriteA
{
printf ( "[A Write Method a = %d, b = %d, c = %d \n", a, b, c);
}
@end
@implementation B
- (void) WriteB
{
printf ( "[B Write Method a = %d, b = %d \n", a, b);
}
@end
int main()
{
B * objb = [[B new] initWithA : 1000 int : 100 int : 10];
printf ( "[main() scope, a = %d \n", objb->a);
[objb WriteB];
[objb WriteA];
[objb free];
return 0;
}
이 프로그램에서 사용하고 있는 A클래스는 public 인스턴스 변수 a, protected 인스턴스 변수 b, private 인스턴스 변수 c를 선언하고 있습니다. 그리고 이들에게 접근할 수 있다는 것을 증명하기 위해 main() 함수에서 B 형 포인터 변수 objb를 통해서 공개 변수 a에 objc->a의 형태로 접근하고 있습니다.
A클래스를 상속하는 하위 클래스 B는 WriteB라는 메서드를 선언하고 이 메서드의 구현에서 노출되는 변수 a와 하위 클래스에서 액세스할 수 있는 변수 b를 액세스 하여 표시합니다. 그러나 하위 클래스에서도 private 변수에는 액세스할 수 없기 때문에 c를 볼 수는 없습니다. 모든 변수에 액세스할 수 있는 인스턴스 변수는 A클래스뿐입니다. A 클래스의 메서드 WriteA에서 모든 인스턴스 변수에 액세스 할 수 있습니다.