인스턴스 변수의 공개 범위

통상, 클래스는 구조체와는 다른 역할이 있기 위해, 데이터형의 제공만으로 클래스가 존재해야 하는 것이 아닙니다. 그러나, 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 에서는, 모든 인스턴스 변수를 표시하는 것이 가능합니다.


Posted by tklee