반응형
클래스 메서드는 메서드를 정의할 때, class 예약어를 추가한 메서드를 말합니다.
클 래스 메서드는 특정 객체에 종속되지 않는 메서드 입니다. 이 말은 Self 레퍼런스가 존재하지 않는다는 것이며, 달리 말하면 멤버 필드 값을 참조할 수 없다는 것입니다. 다음 소스 파일을 컴파일 하면 클래스 메서드인 ClassMethod 내에서는 멤버 필드 값 참조 코드가 모두 에러로 처리됨을 알 수 있습니다.

unit Unit2;

interface

type
  TTestClass = class(TObject)
  private
    FOne: Integer;
    FTwo: string;
  public
    class procedure ClassMethod;
    procedure NormalMethod;
  end;

implementation

class procedure TTestClass.ClassMethod;
begin
  FOne := 10;       // Compile Error
  FTwo :='abcdef';  // Compile Error
end;

procedure TTestClass.NormalMethod;
begin
  FOne := 10;
  FTwo :='abcdef';
end;

end.

멤 버 필드를 참조하지 못한다는 점으로만 판단하면, 클래스 메서드는 별로 사용가치가 없어 보이나, 사실 그렇지 않습니다. 일반 메서드는 반드시 객체를 생성하고 초기화한후에야만 호출할 수 있지만, 클래스 메서드는 객체 생성을 하지 않아도 일반 전역 함수처럼 호출 할 수 있습니다. 다음 코드가 이를 설명합니다.

procedure CallTest;
var
  obj : TTestClass;
begin
  // 클래스 메서드는 클래스명을 참조하여 직접 호출 가능함
  TTestClass.ClassMethod;
  // 클래스 메서드는 생성되지 않는, 즉 초기화하지 않은 객체를 통해서도 호출 가능
  obj.ClassMethod;

  // 일반 메서드는 객체 생성후에야만 호출 가능
  obj := TTestClass.Create;
  obj.NormalMethod;

  // 클래스 메서드는 생성된 객체를 통해서도 호출 가능
  obj.ClassMethod;
  
  obj.Free;

end;


클 래스 메서드를 대체 어떤 경우 사용해야 할까요? 객체 지향 이론에 의하면, 전역 함수는 프로그램 유지 보수를 어렵게 만들기 때문에, 전역함수 대신,  메서드를 사용하라고 권합니다. 이 이론을 따라서, 전역함수를 특정 클래스의 일반 메서드로 정의했다면, 그 메서드를 호출하려면, 앞의 예제에서 봤듯이 항상 객체 생성/파괴와 관련된 코드가 수반되어야 합니다.

반면에 클래스 메서드는 객체 생성과 파괴 없이도 호출할 수 있기 때문에 전역적 함수 역할을 충분히 대신할 수 있다는 이야기 입니다.

즉 클래스 메서드는, 관련된 전역함수들끼리 특정 클래스에 모아두고, 메서드를 전역 함수 처럼 사용할 수 있게 하는 것입니다.

클래스 메서드 사용예로서, 로그인을 처리하는 다음과 같은 클래스를 만들었다고 가정합시다

unit Unit3;

interface.

type
  TLogin = class(TObject)
  public
    class procedure Login;
    class procedure Logout;
  end;

implementation

var
  // 요 파일에서만 참조 가능하도록 implementation 영역에서 변수 정의
  LoginCnt : integer = 0;
  LoginId, Password : String;

class procedure TLogin.Login;
begin
  // Login Process Code
  // Get Id
  // Get Password

  inc(LoginCnt);
  if LoginCnt > 4 then
  begin
    ShowMessage('Max log count limit. Program shut down');
  end;
end;

class procedure TLogin.Logout;
begin
  // Log out
end;

이제 로그인 작업을 처리하려면 다음과 같이 하면 될 것 입니다.

procedure SomeJob;
begin
  TLogin.Login;
end;

유감스럽게도 델파이에는 클래스 메서드는 있으나 클래스 필드는 없습니다. 즉 다음과 같이 코딩할 수는 없습니다.

TLogin = class(TObject)
  private
    class ID : string;      // 클래스 필드는 지원하지 않음. 컴파일 에러
    class Password : string; // 클래스 필드는 지원하지 않음. 컴파일 에러
  public  
    class procedure Login;
    class procedure Logout;
  end;

이 때문에 TLogin 클래스와 밀접한 관계가 있는  LoginCnt, LoginId, Password 등을 멤버 필드로 정의하지 못하고, 유닛 전역적 변수인 implementation 영역에서 정의했습니다. 이 변수들을 멤버 필드로 정의해 버리면 클래스 메서드인 Login은 이 값을 참조할 수가 없기 때문입니다.

결론적으로 이야기해서, 클래스 정의가 어떤 변수와 그 변수를 사용하는 함수들간에 문법적 결합을 설정하는 것처럼, 클래스 메서드란 관련성 있는 전역 함수들 간에 문법적 결합을 설정하는 것입니다.
 


반응형
반응형