Pascal-object-oriented

提供:Dev Guides
移動先:案内検索

パスカル-オブジェクト指向

太陽、地球、月などのさまざまなオブジェクトで作られた宇宙を想像できます。 同様に、ホイール、ステアリング、ギアなどのさまざまなオブジェクトで作られた車を想像できます。 同様に、オブジェクト指向プログラミングの概念があります。これは、すべてをオブジェクトとして想定し、異なるオブジェクトを使用してソフトウェアを実装します。 Pascalでは、実世界のオブジェクトを実装するために使用される2つの構造データ型があります-

  • オブジェクトタイプ
  • クラスの種類

オブジェクト指向の概念

詳細に進む前に、Object-Oriented Pascalに関連する重要なPascal用語を定義しましょう。

  • オブジェクト-オブジェクトは、レコードのようなフィールドを含む特別な種類のレコードです。ただし、レコードとは異なり、オブジェクトにはオブジェクトの一部としてプロシージャと関数が含まれます。 これらのプロシージャと関数は、オブジェクトの型に関連付けられたメソッドへのポインタとして保持されます。
  • クラス-クラスはオブジェクトとほぼ同じ方法で定義されますが、作成方法に違いがあります。 クラスはプログラムのヒープに割り当てられ、オブジェクトはスタックに割り当てられます。 オブジェクト自体ではなく、オブジェクトへのポインタです。
  • クラスのインスタンス化-インスタンス化とは、そのクラスタイプの変数を作成することを意味します。 クラスは単なるポインターであるため、クラス型の変数が宣言されると、オブジェクト全体ではなく、ポインターのみにメモリが割り当てられます。 コンストラクターの1つを使用してインスタンス化された場合のみ、メモリがオブジェクトに割り当てられます。 クラスのインスタンスは「オブジェクト」とも呼ばれますが、Object Pascalオブジェクトと混同しないでください。 このチュートリアルでは、Pascalオブジェクトには「オブジェクト」を、概念オブジェクトまたはクラスインスタンスには「オブジェクト」を記述します。
  • メンバー変数-これらは、クラスまたはオブジェクト内で定義された変数です。
  • メンバー関数-これらは、クラスまたはオブジェクト内で定義された関数またはプロシージャであり、オブジェクトデータにアクセスするために使用されます。
  • メンバーの可視性-オブジェクトまたはクラスのメンバーは、フィールドとも呼ばれます。 これらのフィールドには異なる可視性があります。 可視性とは、メンバーのアクセス可能性、つまり、これらのメンバーがアクセス可能な場所を指します。 オブジェクトには、パブリック、プライベート、保護の3つの可視性レベルがあります。 クラスには、パブリック、プライベート、厳密にプライベート、保護、公開の5つの可視性タイプがあります。 可視性について詳しく説明します。
  • 継承-親クラスの既存の機能を継承することによってクラスが定義される場合、継承されると言われます。 ここで、子クラスは親クラスのすべてまたはいくつかのメンバー関数と変数を継承します。 オブジェクトを継承することもできます。
  • 親クラス-別のクラスによって継承されるクラス。 これは、基本クラスまたはスーパークラスとも呼ばれます。
  • 子クラス-別のクラスから継承するクラス。 これは、サブクラスまたは派生クラスとも呼ばれます。
  • 多態性-これは、同じ機能を異なる目的に使用できるオブジェクト指向の概念です。 たとえば、関数名は同じままですが、引数の数が異なり、異なるタスクを実行できます。 Pascalクラスはポリモーフィズムを実装しています。 オブジェクトはポリモーフィズムを実装しません。
  • オーバーロード-これは、一部またはすべての演算子が引数のタイプに応じて異なる実装を持つポリモーフィズムのタイプです。 同様に、異なる実装で関数をオーバーロードすることもできます。 Pascalクラスはオーバーロードを実装していますが、Objectsは実装していません。
  • データの抽象化-実装の詳細が隠されている(抽象化された)データの表現。
  • カプセル化-すべてのデータとメンバー関数を一緒にカプセル化してオブジェクトを形成する概念を指します。
  • コンストラクタ-クラスまたはオブジェクトからオブジェクトが形成されるたびに自動的に呼び出される特別なタイプの関数を指します。
  • デストラクタ-オブジェクトまたはクラスが削除されるか、スコープ外になると自動的に呼び出される特別なタイプの関数を指します。

Pascalオブジェクトの定義

オブジェクトは、型宣言を使用して宣言されます。 オブジェクト宣言の一般的な形式は次のとおりです-

type object-identifier = object
   private
   field1 : field-type;
   field2 : field-type;
   ...
   public
   procedure proc1;
   function f1(): function-type;
   end;
var objectvar : object-identifier;

2つの整数型データメンバ- length および width と、これらのデータメンバを操作するいくつかのメンバ関数と、長方形を描画するプロシージャを持つRectangleオブジェクトを定義しましょう。

type
   Rectangle = object
   private
      length, width: integer;

   public
      constructor init;
      destructor done;

      procedure setlength(l: inteter);
      function getlength(): integer;

      procedure setwidth(w: integer);
      function getwidth(): integer;

      procedure draw;
end;
var
   r1: Rectangle;
   pr1: ^Rectangle;

オブジェクトを作成した後、そのオブジェクトに関連するメンバー関数を呼び出すことができます。 1つのメンバー関数は、関連オブジェクトのメンバー変数のみを処理できます。

次の例は、2つの長方形オブジェクトの長さと幅を設定し、メンバー関数を呼び出してそれらを描画する方法を示しています。

r1.setlength(3);
r1.setwidth(7);

writeln(' Draw a rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1);
pr1^.setlength(5);
pr1^.setwidth(4);

writeln(' Draw a rectangle: ', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);

以下は、Pascalでオブジェクトを使用する方法を示す完全な例です-

program exObjects;
type
   Rectangle = object
   private
      length, width: integer;

   public
      procedure setlength(l: integer);
      function getlength(): integer;

      procedure setwidth(w: integer);
      function getwidth(): integer;

      procedure draw;
end;
var
   r1: Rectangle;
   pr1: ^Rectangle;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;
begin
   getlength := length;
end;

function Rectangle.getwidth(): integer;
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var
   i, j: integer;
begin
   for i:= 1 to length do
   begin
     for j:= 1 to width do
        write(' * ');
     writeln;
   end;
end;

begin
   r1.setlength(3);
   r1.setwidth(7);

   writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
   new(pr1);
   pr1^.setlength(5);
   pr1^.setwidth(4);

   writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
   pr1^.draw;
   dispose(pr1);
end.

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *

オブジェクトメンバーの可視性

可視性は、オブジェクトメンバのアクセシビリティを示します。 パスカルオブジェクトのメンバーには3種類の可視性があります-

Sr.No Visibility & Accessibility
1

Public

メンバーは、プログラムユニット以外の他のユニットで使用できます。

2

Private

メンバーは現在のユニットでのみアクセス可能です。

3

Protected

メンバーは、親オブジェクトから派生したオブジェクトでのみ使用できます。

デフォルトでは、オブジェクトのフィールドとメソッドはパブリックであり、現在のユニットの外部にエクスポートされます。

Pascalオブジェクトのコンストラクタとデストラクタ-

  • コンストラクタ*は特別なタイプのメソッドであり、オブジェクトが作成されるたびに自動的に呼び出されます。 キーワードコンストラクターでメソッドを宣言するだけで、Pascalでコンストラクターを作成できます。 通常、メソッド名はInitですが、独自の有効な識別子を指定できます。 コンストラクター関数には、好きなだけ引数を渡すことができます。
  • デストラクタ*は、オブジェクトの破壊中に呼び出されるメソッドです。 デストラクタメソッドは、コンストラクタによって作成されたメモリ割り当てを破棄します。

次の例は、Rectangleクラスのコンストラクターとデストラクターを提供します。これは、オブジェクトの作成時に長方形の長さと幅を初期化し、スコープから外れると破棄します。

program exObjects;
type
   Rectangle = object
   private
      length, width: integer;
   public
      constructor init(l, w: integer);
      destructor done;

      procedure setlength(l: integer);
      function getlength(): integer;

      procedure setwidth(w: integer);
      function getwidth(): integer;

      procedure draw;
end;

var
   r1: Rectangle;
   pr1: ^Rectangle;

constructor Rectangle.init(l, w: integer);
begin
   length := l;
   width := w;
end;

destructor Rectangle.done;
begin
   writeln(' Desctructor Called');
end;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;
begin
   getlength := length;
end;

function Rectangle.getwidth(): integer;
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
      writeln;
   end;
end;

begin
   r1.init(3, 7);
   writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
   new(pr1, init(5, 4));

   writeln('Draw a rectangle:', pr1^.getlength(), ' by ',pr1^.getwidth());
   pr1^.draw;
   pr1^.init(7, 9);

   writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
   pr1^.draw;
   dispose(pr1);
   r1.done;
end.

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *
Draw a rectangle: 7 by 9
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
Destructor Called

Pascalオブジェクトの継承

Pascalオブジェクトは、オプションで親オブジェクトから継承できます。 次のプログラムは、Pascalオブジェクトの継承を示しています。 Rectangleオブジェクトを継承する TableTop という名前の別のオブジェクトを作成してみましょう。

program exObjects;
type
   Rectangle = object
   private
      length, width: integer;
   public
      procedure setlength(l: integer);
      function getlength(): integer;
      procedure setwidth(w: integer);
      function getwidth(): integer;
      procedure draw;
end;

TableTop = object (Rectangle)
   private
     material: string;
   public
      function getmaterial(): string;
      procedure setmaterial( m: string);
      procedure displaydetails;
      procedure draw;
end;

var
   tt1: TableTop;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;
begin
   getlength := length;
end;

function Rectangle.getwidth():integer;
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' *');
      writeln;
  end;
end;

function TableTop.getmaterial(): string;
begin
   getmaterial := material;
end;

procedure TableTop.setmaterial( m: string);
begin
   material := m;
end;

procedure TableTop.displaydetails;
begin
   writeln('Table Top: ', self.getlength(), ' by ' , self.getwidth());
   writeln('Material: ', self.getmaterial());
end;

procedure TableTop.draw();
var
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write('* ');
   writeln;
   end;
   writeln('Material: ', material);
end;

begin
   tt1.setlength(3);
   tt1.setwidth(7);
   tt1.setmaterial('Wood');
   tt1.displaydetails();
   writeln;
   writeln('Calling the Draw method');
   tt1.draw();
end.

以下は、注意すべき重要な点です-

  • オブジェクト_Tabletop_は、Rectangleオブジェクトのすべてのメンバーを継承しています。
  • _TableTop_にもdrawメソッドがあります。 _TableTop_オブジェクトを使用して_draw_メソッドが呼び出されると、TableTopの描画が呼び出されます。
  • オブジェクトの現在のインスタンスを参照する self という名前の暗黙的なインスタンスがあります。

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Table Top: 3 by 7
Material: Wood

Calling the Draw Method
* * * * * * *
* * * * * * *
* * * * * * *
Material: Wood