StartprogrammingusingObjectPascal:Inheritance
상속
객체지향 프로그래밍 에서의 상속은 기존의 클래스로부터 새로운 클래스를 만들고 기존의 메서드와 속성을 물려받음을 의미합니다. 기존의 속성과 메서드를 물려받고 나면, 새 클래스에 새 메서드와 속성을 추가할 수 있습니다.
상속의 예제로서 이전 문자열 큐 클래스로부터 새로운 정수형 큐 클래스를 만들려고 합니다. 정수형 큐를 처음부터 완전히 새로 작성하는 대신에 문자열 큐로부터 상속할 수 있습니다.
문자열 큐로부터 상속하려면, 새 유닛을 추가하고 uses 절에 문자열 큐를 놓습니다. 이제 새로운 정수형 큐를 다음과 같이 선언합니다.
TIntQueue = class(TQueue)
새 유닛의 이름은 IntQueue이고, 두 가지 새로운 메서드 PutInt와 GetInt를 도입합니다.
TIntQueue 클래스가 들어있는 유닛의 전체 코드입니다.
unit IntQueue;
// This unit contains TIntQueue class, which is inherits TQueue
// class and adds PutInt, GetInt methods to be used with
// Integer queue
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Queue;
type
{ TIntQueue }
TIntQueue = class(TQueue)
public
function PutInt(AValue: Integer): Integer;
function GetInt(var AValue: Integer): Boolean;
end;
implementation
{ TIntQueue }
function TIntQueue.PutInt(AValue: Integer): Integer;
begin
Result:= Put(IntToStr(AValue));
end;
function TIntQueue.GetInt(var AValue: Integer): Boolean;
var
StrValue: string;
begin
Result:= Get(StrValue);
if Result then
AValue:= StrToInt(StrValue);
end;
end.
참고로 부모 클래스 TQueue에 Create, Destroy, Count 메서드가 이미 존재하기 때문에 이들 메서드를 새로 작성하지 않았습니다.
새 정수형 큐 클래스를 사용하기 위해 새 프로그램을 만들고 이 구성요소들을 추가했습니다.
유닛의 코드입니다.
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics,
Dialogs, IntQueue, StdCtrls;
type
{ TfmMain }
TfmMain = class(TForm)
bbAdd: TButton;
bbCount: TButton;
bbGet: TButton;
edCustomerID: TEdit;
Label1: TLabel;
Memo1: TMemo;
procedure bbAddClick(Sender: TObject);
procedure bbCountClick(Sender: TObject);
procedure bbGetClick(Sender: TObject);
procedure FormClose(Sender: TObject;
var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
MyQueue: TIntQueue;
{ public declarations }
end;
var
fmMain: TfmMain;
implementation
{ TfmMain }
procedure TfmMain.FormCreate(Sender: TObject);
begin
MyQueue:= TIntQueue.Create;
end;
procedure TfmMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
MyQueue.Free;
end;
procedure TfmMain.bbCountClick(Sender: TObject);
begin
Memo1.Lines.Add('Queue length is: ' + IntToStr(MyQueue.Count));
end;
procedure TfmMain.bbAddClick(Sender: TObject);
var
APosition: Integer;
begin
APosition:= MyQueue.PutInt(StrToInt(edCustomerID.Text));
Memo1.Lines.Add(edCustomerID.Text + ' has been added as # '
+ IntToStr(APosition + 1));
end;
procedure TfmMain.bbGetClick(Sender: TObject);
var
ACustomerID: Integer;
begin
if MyQueue.GetInt(ACustomerID) then
begin
Memo1.Lines.Add('Got: Customer ID : ' + IntToStr(ACustomerID) +
' from the queue');
end
else
Memo1.Lines.Add('Queue is empty');
end;
initialization
{$I main.lrs}
end.
참고로 TQueue의 속성과 메서드 그리고 추가적으로 TIntQueue의 속성과 메서드를 사용했습니다.
이 경우 본래 TQueue를 기반 클래스 또는 조상이라고 부르며, 새 클래스를 자손이라고 부릅니다.
새 클래스를 만드는 대신에 문자열 큐 유닛을 수정하고 정수형을 다루기 위해 IntPut과 IntGet을 추가할 수 있었지만, 상속을 표현하기 위해 새로운 TIntQueue 클래스를 만들었습니다. 또 다른 이유들이 있습니다. 라자루스의 .ppu와 델파이의 .dcu와 같은 이미 컴파일한 유닛 파일만 가지고 있을 때와 같이 TQueue의 본래 소스 코드를 가지고 있지 못했다고 가정합니다. 이 경우 소스 코드를 볼 수 없고 물론 수정할 수도 없습니다. 상속은 이 큐에 대해 보다 기능적인 추가를 하기 위한 유일한 방법이 될 것입니다