Delphi [델파이 문법] 클래스와 객체 #3
2012.04.18 19:17
클래스 멤버의 가시성
클래스의 모든 멤버는 가시성(visibility)이라는 성질을 가지는데, 이는 예약어 private, protected, public, published 또는 automated 중의 하나입니다. 예를 들면,
위 코드는 Color라는 published 속성을 선언합니다. 가시성은 멤버가 액세스될 수 있는 범 위 및 방법을 결정하는 것으로, private는 최소한의 액세스, protected는 중간 수준으로 액 세스, public, published, automated는 최대한의 액세스를 지정합니다.
멤버의 선언이 자신만의 가시성 지정없이 나타나는 경우 그멤버는 바로 앞 멤버와 같은 가시성을 가집니다. 클래스가 {$M+} 상태에서 컴파일되거나 {$M+} 상태에서 컴파일된 클 래스로부터 파생된 경우, 클래스 선언의 맨 처음에 나타나는 가시성이 지정되지 않은 멤버는 기본적으로 published를 갖게 되고, {$M+} 없이 컴파일된 경우에는 public을 갖게 됩니다. 가독성을 위해 가시성에 따라 클래스 선언을 정리해두는 것이 좋습니다. 모든 private 멤버 를 모아 두고, 그 뒤에는 protected 멤버를 모아 두고, 이런 식입니다. 그러면 각 가시성 예 약어는 한 번만 나타나며 선언의 새“섹션”시작을 표시합니다. 일반적인 클래스 선언은 다음과 같습니다.
자손 클래스를 재선언하면 자손 클래스 멤버의 가시성을 높일 수 있지만, 가시성을 낮출 수 는 없습니다. 예를 들어, protected 속성은 자손 클래스에서 public으로 재선언될 수 있지만 private이 될 수는 없습니다. 또한, published 멤버는 자손 클래스에서 public이 될 수 없습 니다. 자세한 내용은 6장의“속성 오버라이드 및 재선언”을 참조하십시오.
■ private, protected 및 public 멤버
private 멤버는 해당 클래스가 선언된 유닛이나 프로그램 외부에서 보이지 않습니다. 즉, 다 른 모듈에서 private 메소드를 호출할 수 없고 private 필드나 속성을 다른 모듈에서 읽거나 쓸 수 없습니다. 관계가 있는 클래스의 선언을 같은 모듈에 두면, private 멤버에 대한 접근 성을 넓히지 않고도 private 멤버 간에 서로 액세스할 수 있도록 할 수 있습니다.
protected 멤버는 해당 클래스가 선언된 모듈과 해당 클래스의 모든 자손 클래스에서 볼 수 있으며, 자손 클래스가 선언된 모듈에 제한을 받지 않습니다. 즉, protected 멤버가 선언된 클래스로부터 파생된 클래스에 속한 모든 메소드의 구현 바디에서 protected 메소드를 호출 할 수 있고 또 protected 필드나 속성을 읽거나 쓸 수 있습니다. 일반적으로 파생 클래스의 구현에서만 사용할 수 있도록 하려는 멤버들을 protected로 선언합니다. public 멤버는 해당 클래스를 참조할 수 있는 모든 곳에서 보여집니다.
■ strict 가시성 지정자
가시성 지정자 private 및 protected에 더하여, 델파이 컴파일러는 더 강하게 액세스를 제한
할 수 있는 추가 가시성 설정들을 지원합니다. 이 설정들은 strict private와 strict
protected 가시성입니다.
strict private가시성으로 지정된 클래스 멤버는 선언된 클래스 내에서만 액세스 가능합니 다. 이 가시성으로 지정된 멤버들은 같은 유닛 내의 프로시저나 함수에게도 보여지지 않습니 다. strict protected 가시성으로 지정된 클래스 멤버는 선언된 곳과는 무관하게 자신이 선언 된 클래스 안에서, 그리고 모든 파생 클래스 안에서 보여집니다. 나아가서, 인스턴스 멤버들 (class나 class var 키워드 없이 선언된 멤버들)이 strict private나 strict protected로 선언 되면 자신이 속한 클래스의 인스턴스 바깥에서는 액세스가 불가능합니다. 한 클래스의 인스 턴스는 동일 클래스의 다른 인스턴스의 strict private나 strict protected 인스턴스 멤버들 을 액세스할 수 없습니다.
델파이의 전통적인 private 가시성 지정자 는 CLR의 assembly 가시성에 해당합니다. 델파 이의 protected 가시성 지정자 는 CLR의 assembly 혹은 family 가시성에 해당합니다.
■ published 멤버
published 멤버는 public 멤버와 같은 가시성을 가집니다. 차이점은, published 멤버에 대 해서는 런타임 타입 정보(RTTI)가 생성된다는 것입니다. RTTI를 사용하여 응용 프로그램 에서 객체의 필드 및 속성을 동적으로 조회하고 해당 메소드를 찾을 수 있습니다. RTTI는 폼 파일을 저장하고 로드할 때 속성의 값을 액세스하고, Object Inspector에서 속성을 표시 하며, 이벤트 핸들러라는 특정 메소드를 이벤트라는 특정 속성과 연결할 수 있습니다. published 속성은 특정 데이터 타입에 제한됩니다. 서수(ordinal), 문자열, 클래스, 인터페 이스, variant, 메소드 포인터 타입은 published로 선언될 수 있습니다. 집합 타입의 경우에 도그시작및마지막의서수값이0과31사이라면가능합니다.(다시말해,집합타입은바 이트, 워드 또는 더블 워드에 맞아야 합니다.) Real48을 제외한 실수 타입들도 published로 선언될 수 있습니다. 배열 타입의 속성(아래에서 설명할 배열 속성과 다름)은 published로 선언될 수 없습니다.
일부 속성들은 published로 선언할 수 있더라도 스트리밍 시스템에서 완벽하게 지원되지 않 습니다. 이러한 속성에는 레코드 타입의 속성, published 가능한 모든 배열 속성“( 속성”절의“배열 속성”참조), 익명 값을 포함하는 열거 타입(4장의“순서값이 지정된 열거 타입“ 참 조)의 속성이 포함됩니다. 이러한 종류의 속성을 published로 선언하는 경우 Object Inspector에서 해당 속성이 제대로 표시되지 않거나 객체가 디스크에 스트리밍될 때 속성 값이 유지되지 않습니다.
모든 메소드는 published가 될 수 있지만 클래스는 같은 이름으로 오버로드된 두 개 이상의
메소드를 published로 만들 수 없습니다. 필드는 클래스나 인터페이스 타입인 경우에만
published가 될 수 있습니다.
클래스는 {$M+} 상태에서 컴파일되거나 {$M+} 상태에서 컴파일된 클래스의 자손이 아니 면 published 멤버를 가질 수 없습니다. published 멤버가 있는 대부분의 클래스는 {$M+} 상태에서 컴파일된 TPersistent에서 파생되므로 $M 지시어를 사용할 필요는 거의 없습니다.
■ automated 멤버
automated 멤버는 public 멤버와 같은 가시성을 가집니다. 차이점은, automated 멤버의 경우 오토메이션 타입 정보(오토메이션 서버에 필요)가 생성된다는 것입니다. automated 예약어는 하위 호환성을 위해 유지됩니다. ComObj 유닛의 TAutoObject 클래스는 automated를 사용하지 않습니다.
automated로 선언된 메소드와 속성에는 다음과 같은 제한 사항이 따릅니다.
- 모든 속성, 배열 속성 파라미터, 메소드 파라미터, 함수 결과의 타입은 automated 가능해야 합 니다. automated 가능 타입은 Byte, Currency, Real, Double, Longint, Integer, Single, Smallint, AnsiString, WideString, TDateTime, Variant, OleVariant, WordBool, 그리고 모 든 인터페이스 타입들입니다.
- 메소드 선언에서는 기본인 register 호출 규칙을 사용해야 합니다. 메소드 선언은 가상(virtual) 일 수 있지만 동적(dynamic)일 수는 없습니다.
- 속성 선언은 액세스 지정자(read 및 write)를 포함할 수 있지만 다른 지정자(index, stored, default 및 nodefault)는 허용되지 않습니다. 액세스 지정자 는 기본인 register 호출 규칙을 사용하는 메소드 식별자를 써야 하며, 필드 식별자는 허용되지 않습니다.
- 속성 선언에서는 타입을 지정해야 합니다. 속성 오버라이드는 허용되지 않습니다.
automated 메소드나 속성의 선언에는 dispid 지시어를 포함할 수 있습니다. dispid 지시어 에 이미 사용된 ID를 지정하면 에러가 발생합니다.
dispid 지시어는 멤버에 대한 오토메이션 디스패치 ID를 지정하는 정수 상수의 앞에 있어야 합니다. 그렇지 않으면 컴파일러는 클래스 및 해당 조상의 메소드나 속성으로 사용된 최대
디스패치 ID보다 큰 디스패치 ID를 멤버에게 지정합니다.
참조링크
http://tech.devgear.co.kr/devgearbook
델파이 프로그래밍 언어 - 엠바카데로 저 | 박지훈 역 (2009년)