StartprogrammingusingObjectPascal:Inheritance

From 흡혈양파의 번역工房
Jump to: navigation, search

상속

객체지향 프로그래밍 에서의 상속은 기존의 클래스로부터 새로운 클래스를 만들고 기존의 메서드와 속성을 물려받음을 의미합니다. 기존의 속성과 메서드를 물려받고 나면, 새 클래스에 새 메서드와 속성을 추가할 수 있습니다.

상속의 예제로서 이전 문자열 큐 클래스로부터 새로운 정수형 큐 클래스를 만들려고 합니다. 정수형 큐를 처음부터 완전히 새로 작성하는 대신에 문자열 큐로부터 상속할 수 있습니다.

문자열 큐로부터 상속하려면, 새 Unit을 추가하고 uses 절에 문자열 큐를 놓습니다. 이제 새로운 정수형 큐를 다음과 같이 선언합니다.

TIntQueue = class(TQueue)

새 Unit의 이름은 IntQueue이고, 두 가지 새로운 메서드 PutIntGetInt를 도입하였습니다.

TIntQueue 클래스가 들어있는 Unit의 전체 코드입니다.

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.

참고로 부모 클래스 TQueueCreate, Destroy, Count 메서드가 이미 존재하기 때문에 이들 메서드를 새로 작성하지 않았습니다.

새 정수형 큐 클래스를 사용하기 위해 새 프로그램을 만들고 이 구성요소들을 추가했습니다.

Lazarus 13.png

Unit의 코드입니다.

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를 기반 클래스 또는 부모 클래스라고 부르며, 새 클래스를 자식 클래스라고 부릅니다.


새 클래스를 만드는 대신에 문자열 큐 Unit을 수정하고 정수형을 다루기 위해 IntPutIntGet을 추가할 수 있었지만, 상속을 표현하기 위해 새로운 TIntQueue 클래스를 만들었습니다. 또 다른 이유들이 있습니다. 라자루스의 .ppu와 델파이의 .dcu와 같은 이미 컴파일한 Unit 파일만 가지고 있을 때와 같이 TQueue의 본래 소스 코드를 가지고 있지 못했다고 가정해봅니다. 이 경우 소스 코드를 볼 수 없고 물론 수정할 수도 없습니다. 상속은 이 큐에 대해 보다 기능적인 추가를 하기 위한 유일한 방법이 될 것입니다.