이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

객체 배열 인덱싱

디폴트 인덱스 참조 및 값 할당

MATLAB® 클래스는 기본적으로 객체 배열 인덱싱을 지원합니다. 대부분의 클래스 설계에서는 이 동작을 수정할 필요가 없습니다.

배열을 사용하면 첨자 표기법을 사용하여 배열의 요소를 참조하고 할당할 수 있습니다. 이 표기법은 특정 배열 요소의 인덱스를 지정합니다. 예를 들어, 숫자로 구성된 두 배열을 생성한다고 가정하겠습니다(randi 및 결합 사용).

1에서 9까지의 정수로 구성된 3x4 배열을 생성합니다.

A = randi(9,3,4)
A =

     4     8     5     7
     4     2     6     3
     7     5     7     7

숫자 3, 6, 9로 구성된 1x3 배열을 생성합니다.

B = [3 6 9];

인덱스 값을 괄호로 묶어 사용하여 하나의 배열의 요소를 참조하고 다른 하나의 배열의 요소에 할당합니다.

B(2) = A(3,4);
B
B =
     3     7     9

인덱스 참조를 포함하는 명령문을 실행하면

C = A(3,4);

MATLAB이 내장 subsref 함수를 호출하여 이 명령문을 해석하는 방법을 결정합니다. 이와 유사하게 인덱스 참조 값 할당을 포함하는 명령문을 실행하면

C(4) = 7;

MATLAB이 내장 subsasgn 함수를 호출하여 이 명령문을 해석하는 방법을 결정합니다.

MATLAB의 디폴트 subsref 함수와 subsasgn 함수는 사용자 정의 객체에서도 동작합니다. 예를 들어, 동일한 클래스의 객체로 구성된 배열을 생성한다고 가정하겠습니다.

for k=1:3
   objArray(k) = MyClass;
end

객체 배열 objArray의 두 번째 요소를 참조하면 k = 2일 때 생성된 객체가 반환됩니다.

D = objArray(2);
class(D)
ans =

MyClass

동일한 클래스의 객체로 구성된 배열에 객체를 할당하거나 초기화되지 않은 변수를 할당할 수 있습니다.

newArray(3,4) = D;

객체로 구성된 배열은 MATLAB에서 숫자형 배열과 매우 비슷하게 동작합니다. 특수 메서드를 구현하여 클래스에 표준 배열 동작을 제공할 필요가 없습니다.

배열 인덱싱에 대한 자세한 내용은 배열 인덱싱 항목을 참조하십시오.

수정할 수 있는 항목

subsrefsubsasgn이라는 클래스 메서드를 구현하여 클래스 인덱스 참조 및/또는 값 할당 동작을 수정할 수 있습니다. 구문 설명은 해당 함수 도움말 페이지를 참조하십시오.

subsref 메서드 또는 subsasgn 메서드를 클래스에 추가하면 MATLAB이 내장 함수 대신 클래스 메서드를 호출합니다. 따라서, 클래스가 지원하도록 하려는 모든 인덱스 참조 및 대입(할당) 연산을 클래스 메서드에 모두 구현해 두어야 합니다. 다음과 같은 연산을 예로 들 수 있습니다.

  • 클래스 메서드에 대한 점 표기법 호출

  • 속성을 포함하는 점 표기법 참조 및 값 할당

  • 소괄호 '()'를 사용한 인덱싱

  • 중괄호 '{}'를 사용한 인덱싱

subsref 메서드와 subsasgn 메서드를 구현하면 클래스의 객체에 대한 인덱싱 표현식 해석을 완벽하게 제어할 수 있습니다. MATLAB이 기본적으로 제공하는 동작의 범위를 구현하는 것이 중요합니다.

인덱싱 동작을 수정하는 경우

객체 배열에 디폴트 인덱싱을 사용하고 속성 및 메서드를 액세스하는 데 점 표기법을 사용하면 사용자 정의 객체가 내장 클래스처럼 동작할 수 있습니다. 예를 들어, 숫자형 데이터로 구성된 배열을 포함하는 Data라는 속성으로 클래스를 정의한다고 가정하겠습니다.

다음 명령문은

obj.Data(2,3)

배열의 두 번째 행과 세 번째 열에 포함된 값을 반환합니다. 객체로 구성된 배열이 있는 경우 다음과 같은 표현식을 사용하십시오.

objArray(3).Data(2,3)

이 명령문은 배열의 세 번째 요소에 대한 두 번째 행과 세 번째 열에 포함된 값을 반환합니다.

클래스 설계에 MATLAB 디폴트 동작과 다른 동작이 필요한 경우 디폴트 인덱싱 동작을 수정하십시오.

메서드 내에서 호출되는 내장 subsref 및 subsasgn

MATLAB은 오버로드된 메서드 내에서 클래스로 정의된 subsref 메서드 또는 subsasgn 메서드를 호출하지 않습니다. 클래스 메서드 내에서는 MATLAB이 항상 내장 subsref 함수와 subsasgn 함수를 호출합니다. 그리고, 클래스로 정의된 subsref 메서드와 subsasgn 메서드 내에서도 마찬가지입니다.

예를 들어, 클래스 메서드 내에서 다음 점 참조는

obj.Prop

내장 subsref 함수를 호출합니다. 클래스로 정의된 subsref 메서드를 호출하려면 다음을 사용하십시오.

subsref(obj,substruct('.','Prop'))

메서드에 클래스로 정의된 subsref 메서드 또는 subsasgn 메서드의 기능이 필요할 때마다 클래스가 오버로드된 메서드를 함수로 호출해야 합니다. '()', '{}' 또는 '.' 연산자를 사용하지 마십시오.

예를 들어, 클래스를 정의하여 다항식을 표현한다고 가정하겠습니다. 이 클래스는 독립 변수의 값이 첨자와 동일한 다항식을 실행하는 subsref 메서드를 가집니다. 이 명령문이 다음과 같은 계수를 갖는 다항식을 정의한다고 가정하겠습니다.

p = polynom([1 0 -2 -5]);

결과로 생성되는 다항식에 대한 MATLAB 표현식은 다음과 같습니다.

x^3 - 2*x - 5

아래 첨자 표현식은 x = 3에서의 다항식의 값을 반환합니다.

p(3)
ans =
    16

다른 클래스 메서드에 이 기능을 사용해야 한다고 가정하겠습니다. 이렇게 하려면 subsref 함수를 직접 호출하십시오. evalEqual 메서드는 두 개의 polynom 객체와 다항식을 실행할 지점의 값을 받습니다.

methods
   function ToF = evalEqual(p1,p2,x)
      % Create arguments for subsref
      subs.type = '()';
      subs.subs = {x};
      % Need to call subsref explicitly 
      y1 = subsref(p1,subs);
      y2 = subsref(p2,subs);
      if y1 == y2
         ToF = true;
      else 
         ToF = false;
      end
   end
end

이 동작을 통해 표준 MATLAB 인덱싱을 사용하여 특화된 동작을 구현할 수 있습니다. 내장 인덱싱과 클래스로 수정된 인덱싱 모두를 사용하는 방법에 대한 예제는 Class with Modified Indexing 항목을 참조하십시오.

액세스 특성을 재정의하지 않도록 방지하기

subsref가 클래스 메서드이기 때문에 프라이빗 클래스 멤버에 액세스할 수 있습니다. 다양한 유형의 참조를 처리할 때 프라이빗 메서드 및 속성에 대한 액세스를 의도치 않게 부여하지 않도록 방지해야 합니다. 프라이빗 속성 xy를 갖는 클래스에 대해 정의된 다음과 같은 subsref 메서드가 있다고 가정하겠습니다.

classdef MyPlot
   properties (Access = private)
      x
      y
   end
   properties
      Maximum
      Minimum
      Average
   end
   methods
      function obj = MyPlot(x,y)
         obj.x = x;
         obj.y = y;
         obj.Maximum = max(y);
         obj.Minimum = min(y);
         obj.Average = mean(y);
      end
      function B = subsref(A,S)
         switch S(1).type
            case '.'
               switch S(1).subs
                  case 'plot'
                     % Reference to A.x and A.y call built-in subsref
                     B = plot(A.x,A.y);
                  otherwise
                     % Enable dot notation for all properties and methods
                     B = A.(S.subs);
               end
         end
      end
   end
end

subsref를 통해 점 표기법을 사용하여 이름을 'plot'으로 하여 플롯을 생성할 수 있습니다. 다음 명령문은

obj = MyPlot(1:10,1:10);
h = obj.plot;

plot 함수를 호출하고 그래픽스 객체에 대한 핸들을 반환합니다.

메서드 및 속성 이름을 일일이 코딩할 필요가 없습니다. 내부 switch 블록의 otherwise 코드는 case 문에서 명시적으로 지정하지 않는 이름 참조를 관리합니다. 하지만 이 기법을 사용하면 점 표기법을 통해 프라이빗 클래스 멤버와 보호 클래스 멤버가 노출됩니다. 예를 들어, 다음 명령문을 사용하여 프라이빗 속성 x를 참조할 수 있습니다.

obj.x
ans =

     1     2     3     4     5     6     7     8     9    10

프라이빗 속성이나 보호 속성에 대한 값 할당을 지원하는 subsasgn 메서드를 작성할 때에도 동일한 문제가 발생할 수 있습니다. subsref 메서드와 subsasgn 메서드에서 클래스 설계 위반을 방지하려면 특정 속성과 메서드 이름을 명시적으로 일일이 코딩해야 할 수 있습니다.

관련 항목