Main Content

클래스 멤버 액세스

기본 정보

이 섹션에 나와 있는 자료는 다음 개념에 대한 이해를 바탕으로 합니다.

 용어 및 개념

 클래스 멤버에 대한 액세스에 가능한 값

액세스 제어 목록을 사용하는 응용 사례

액세스 제어 목록을 통해 특정 클래스 속성, 메서드, 이벤트에 대한 액세스를 제어할 수 있습니다. 액세스 제어 목록은 클래스 멤버 단위로 액세스를 부여할 클래스의 목록을 지정합니다.

이 기법은 클래스 시스템을 설계할 때 더욱 큰 유연성과 제어 기능을 제공합니다. 예를 들어, 액세스 제어 목록을 사용하여 개별 클래스를 정의하되, 클래스 시스템 외부에서는 클래스 멤버에 액세스할 수 없게 할 수 있습니다.

클래스 멤버에 대한 액세스 지정하기

멤버 액세스 특성 문에서 특정 클래스 멤버에 액세스하도록 허용하는 클래스를 지정할 수 있습니다. 예를 들어, 다음과 같이 합니다.

methods (Access = {?ClassName1,?ClassName2,...})

클래스의 matlab.metadata.Class 객체를 사용하여 액세스 목록의 클래스를 참조합니다. 둘 이상의 클래스를 지정하려면 matlab.metadata.Class 객체로 구성된 셀형 배열을 사용하십시오. 네임스페이스에 포함된 클래스를 참조할 때에는 네임스페이스 이름을 사용해야 합니다.

참고

matlab.metadata.Class 객체(? 연산자로 생성)를 명시적으로 지정하되, 함수 또는 다른 MATLAB 표현식에서 반환된 값으로는 지정하지 마십시오.

MATLAB이 특성 값을 해석하는 방법

  • 클래스 목록에 액세스를 부여하면 액세스가 다음으로만 제한됩니다.

    • 정의 클래스

    • 목록에 포함된 클래스

    • 목록에 포함된 클래스의 서브클래스

  • 액세스 목록에 정의 클래스를 포함시키면 정의 클래스의 모든 서브클래스에 대한 액세스도 부여됩니다.

  • MATLAB은 클래스를 불러올 때에만 액세스 목록에 포함된 클래스에 대한 참조를 확인합니다. MATLAB이 액세스 목록에 포함된 클래스를 찾을 수 없는 경우 해당 클래스는 실질적으로 액세스에서 제거됩니다.

  • MATLAB은 목록에 있지만 확인되지 않은 matlab.metadata.Class 항목을 빈 matlab.metadata.Class 객체로 바꿉니다.

  • 빈 액세스 목록(즉, 빈 셀형 배열)은 private 액세스와 동일합니다.

메타클래스 객체 지정하기

? 연산자와 클래스 이름만 사용하여 matlab.metadata.Class 객체를 생성합니다. 특성에 할당되는 값은 허용된 다음과 같은 특성 값을 반환하는 함수를 비롯하여 다른 MATLAB 표현식을 포함할 수 없습니다.

  • matlab.metadata.Class 객체

  • matlab.metadata.Class 객체로 구성된 셀형 배열

  • public, protected 또는 private

이러한 값은 이 섹션의 예제 코드에 표시된 것처럼 명시적으로 지정해야 합니다.

액세스 목록을 갖는 속성

다음 예제 클래스에서는 읽기 액세스(GetAccess)를 클래스에 부여하는 속성의 동작을 보여줍니다. GrantAccess 클래스는 GetAccessProp1 속성의 NeedAccess 클래스에 부여합니다.

classdef GrantAccess
   properties (GetAccess = ?NeedAccess)
      Prop1 = 7
   end
end

NeedAccess 클래스는 GrantAccess Prop1 값을 사용하는 메서드를 정의합니다. dispObj 메서드는 Static 메서드로 정의되지만, 일반 메서드일 수 있습니다.

classdef NeedAccess
   methods (Static)
      function dispObj(GrantAccessObj)
         disp(['Prop1 is: ',num2str(GrantAccessObj.Prop1)])
      end
   end
end

Prop1에 대한 Get 액세스는 프라이빗이므로 클래스 정의 외부에서 속성에 액세스하려고 하면 MATLAB이 오류를 반환합니다. 명령줄에서 다음을 실행하는 경우를 예로 들 수 있습니다.

a = GrantAccess;
a.Prop1
Getting the 'Prop1' property of the 'GrantAccess' class is not allowed.

하지만 MATLAB에서는 NeedAccess 클래스를 통해 Prop1에 액세스할 수 있도록 허용합니다.

NeedAccess.dispObj(a)
Prop1 is: 7

액세스 목록을 갖는 메서드

메서드에 대한 액세스가 부여된 클래스는 다음을 수행할 수 있습니다.

  • 정의 클래스의 인스턴스를 사용하여 메서드를 호출할 수 있습니다.

  • 동일한 이름으로 자체 메서드를 정의할 수 있습니다(서브클래스가 아닌 경우에 한함).

  • 메서드를 정의하는 슈퍼클래스가 액세스 목록에 자기 자신 또는 서브클래스를 포함하는 경우에만 서브클래스의 메서드를 오버라이드할 수 있습니다.

다음 예제 클래스에서는 액세스 목록에 포함된 다른 클래스의 메서드에서 호출된 메서드의 동작을 보여줍니다. AcListSuper 클래스는 AcListNonSub 클래스에 m1 메서드에 대한 액세스를 부여합니다.

classdef AcListSuper
   methods (Access = {?AcListNonSub})
      function obj = m1(obj)
         disp ('Method m1 called')
      end
   end
end

AcListNonSubm1의 액세스 목록에 포함되어 있으므로 해당 메서드가 AcListSuper의 인스턴스를 사용하여 m1을 호출할 수 있습니다.

classdef AcListNonSub
   methods
      function obj = nonSub1(obj,AcListSuper_Obj)
         % Call m1 on AcListSuper class
         AcListSuper_Obj.m1;
      end
      function obj = m1(obj)
         % Define a method named m1
         disp(['Method m1 defined by ',class(obj)])
      end
   end
end

두 클래스 모두에 대한 객체를 생성합니다.

a = AcListSuper;
b = AcListNonSub;

AcListNonSub 메서드를 사용하여 AcListSuperm1 메서드를 호출합니다.

b.nonSub1(a);
Method m1 called

AcListNonSubm1 메서드를 호출합니다.

b.m1;
Method m1 defined by AcListNonSub

액세스가 부여되지 않은 서브클래스

메서드에 대한 액세스 목록에 정의 클래스를 포함시키면 정의 클래스에서 파생된 모든 서브클래스에도 액세스할 수 있습니다. 메서드에 액세스 목록이 지정되어 있는 클래스에서 서브클래스를 파생하는데 정의 클래스가 액세스 목록에 포함되어 있지 않다면 다음과 같은 특성을 갖게 됩니다.

  • 서브클래스 메서드가 슈퍼클래스 메서드를 호출할 수 없습니다.

  • 서브클래스 메서드가 액세스 목록에 포함된 클래스의 인스턴스를 사용하여 간접적으로 슈퍼클래스 메서드를 호출할 수 있습니다.

  • 서브클래스가 슈퍼클래스 메서드를 오버라이드할 수 없습니다.

  • 슈퍼클래스 메서드 액세스 목록에 포함되어 있지만 서브클래스 메서드가 아니라면 슈퍼클래스 메서드를 호출할 수 있습니다.

예를 들어, AcListSubAcListSuper의 서브클래스라고 가정하겠습니다. AcListSuper 클래스가 메서드 m1에 대한 액세스 목록을 정의합니다. 하지만 이 목록에 AcListSuper가 포함되어 있지 않아 AcListSuper의 서브클래스가 메서드 m1에 액세스할 수 없는 상황입니다.

classdef AcListSub < AcListSuper
   methods
      function obj = sub1(obj,AcListSuper_Obj)
         % Access m1 via superclass object (***NOT ALLOWED***)
         AcListSuper_Obj.m1;
      end
      function obj = sub2(obj,AcListNonSub_Obj,AcListSuper_obj)
         % Access m1 via object that is in access list (is allowed)
         AcListNonSub_Obj.nonSub1(AcListSuper_Obj);
      end
   end
end

슈퍼클래스 메서드를 직접적으로 호출할 수 없음

sub1 메서드에서 슈퍼클래스의 m1 메서드를 호출하려고 하면 서브클래스가 m1에 대한 액세스 목록에 없으므로 오류가 발생합니다.

a = AcListSuper;
c = AcListSub;
c.sub1(a);
Cannot access method 'm1' in class 'AcListSuper'.

Error in AcListSub/sub1 (line 4)
         AcListSuper_Obj.m1;

슈퍼클래스 메서드를 간접적으로 호출할 수 있음

슈퍼클래스 메서드 액세스 목록에 포함된 클래스의 객체를 사용하여 해당 메서드에 대한 액세스를 가지지 않는 서브클래스에서 슈퍼클래스 메서드를 호출할 수 있습니다.

AcListSubsub2 메서드는 m1의 액세스 목록에 포함된 클래스(AcListNonSub)의 메서드를 호출합니다. 메서드 nonSub1은 슈퍼클래스의 m1 메서드에 액세스할 수 있습니다.

a = AcListSuper;
b = AcListNonSub;
c = AcListSub;
c.sub2(b,a);
Method m1 called

슈퍼클래스 메서드를 재정의할 수 없음

슈퍼클래스가 메서드에 대한 액세스 목록에 포함되어 있지 않은 경우 이러한 서브클래스는 이름이 동일한 메서드를 정의할 수 없습니다. 이 동작은 메서드 Accessprivate으로 명시적으로 선언된 경우와 동일하지 않습니다.

예를 들어, 다음 메서드를 AcListSub 클래스 정의에 추가하면 클래스를 인스턴스화하려고 할 때 오류가 발생합니다.

methods (Access = {?AcListNonSub})
   function obj = m1(obj)
      disp('AcListSub m1 method')
   end
end
c = AcListSub;
Class 'AcListSub' is not allowed to override the method 'm1' because neither it nor its
superclasses have been granted access to the method by class 'AcListSuper'.

서브클래스를 통해 목록에 포함된 클래스에서 슈퍼클래스 호출하기

AcListNonSub 클래스는 m1 메서드 액세스 목록에 포함되어 있습니다. 이 클래스는 AcListSub 클래스의 객체를 사용하여 m1 메서드를 호출하는 메서드를 정의할 수 있습니다. AcListSub는 메서드 m1에 대한 액세스 목록에 포함되어 있지 않지만 AcListSuper의 서브클래스입니다.

예를 들어, 다음 메서드를 AcListNonSub 클래스에 추가해 보겠습니다.

methods
   function obj = nonSub2(obj,AcListSub_Obj)
      disp('Call m1 via subclass object:')
      AcListSub_Obj.m1;
   end
end

nonSub2 메서드를 호출하면 슈퍼클래스의 m1 메서드가 실행됩니다.

b = AcListNonSub;
c = AcListSub;
b.nonSub2(c);
Call m1 via subclass object:
Method m1 called

이 동작은 슈퍼클래스의 객체를 대신할 수 있는 서브클래스 객체의 동작과 일치합니다.

액세스 목록이 지정된 추상 메서드

Abstract로 선언된 메서드를 포함하는 클래스가 추상 클래스입니다. 클래스 정의에 선언된 함수 시그니처를 사용하여 추상 메서드를 구현하는 것이 서브클래스의 역할입니다.

추상 메서드에 액세스 목록이 지정된 경우 액세스 목록에 포함된 클래스만 그 메서드를 구현할 수 있습니다. 액세스 목록에 포함되지 않은 서브클래스는 추상 메서드를 구현할 수 없으므로 해당 서브클래스 자체가 추상 클래스입니다.

관련 항목