Difference between revisions of "Object Oriented Programming with Free Pascal and Lazarus/ja"

From Free Pascal wiki
Jump to navigationJump to search
 
(10 intermediate revisions by the same user not shown)
Line 67: Line 67:
 
もし、血を見るのが嫌ならば、同様の理屈が車庫から、修理場へ運ばれる自動車にも適用できる。
 
もし、血を見るのが嫌ならば、同様の理屈が車庫から、修理場へ運ばれる自動車にも適用できる。
 
それは以下よりなっているだろう:
 
それは以下よりなっているだろう:
* 自動車自身
+
* 自動車自体
 
* 所有者によって保存されている、登録証、車両ナンバー(車両ナンバープレートを含む)、保険証、購入の領収書、部品、修理などの書類
 
* 所有者によって保存されている、登録証、車両ナンバー(車両ナンバープレートを含む)、保険証、購入の領収書、部品、修理などの書類
 
* 燃料消費履歴
 
* 燃料消費履歴
Line 82: Line 82:
 
Free Pascal/Lazarusでいくつかのコントロールを持つ簡単なフォームを作ることを考える。
 
Free Pascal/Lazarusでいくつかのコントロールを持つ簡単なフォームを作ることを考える。
  
<div class="floatleft">[[Image:ObjectInspector-TForm.png]]</div>
+
<div class="floatleft">[[Image:ObjectInspector-TForm-ja.png]]</div>
<div class="floatright">[[Image:BlankForm.png]]</div>
+
<div class="floatright">[[Image:BlankForm-ja.png]]</div>
  
 
Lazarus IDEを起動すると、プログラマにはフォーム設計の様々なコントロールや、オブジェクトを置くことを促す、空のテンプレートがもたらされる。
 
Lazarus IDEを起動すると、プログラマにはフォーム設計の様々なコントロールや、オブジェクトを置くことを促す、空のテンプレートがもたらされる。
Line 99: Line 99:
 
フォーム上の物理的な画像であるボタンは、そのプロパティとイベントハンドラと相まって、パスカルでは単一の実体'''オブジェクト(Object)'''とみなされる。
 
フォーム上の物理的な画像であるボタンは、そのプロパティとイベントハンドラと相まって、パスカルでは単一の実体'''オブジェクト(Object)'''とみなされる。
  
<div class="floatleft">[[Image:ObjectInspector-TButton.png]]</div>
+
<div class="floatleft">[[Image:ObjectInspector-TButton-ja.png]]</div>
<div class="floatright">[[Image:FormWithButton.png]]</div>
+
<div class="floatright">[[Image:FormWithButton-ja.png]]</div>
<div class="floatright">[[Image:Source_FormWithButton1.png‎ ]]</div>
+
<div class="floatright">[[Image:Source FormWithButton1-ja.png‎ ]]</div>
  
 
== 標準パスカルに対するオブジェクト指向拡張 ==
 
== 標準パスカルに対するオブジェクト指向拡張 ==
Line 108: Line 108:
 
=== オブジェクト ===
 
=== オブジェクト ===
  
An Object is a special kind of record. The record contains all the fields that
+
オブジェクトは特別な種類のレコードである。 レコードには、次のすべてのフィールドが含まれる。
are declared in the object's definition (just like a conventional record), but now procedures and functions can be declared as if they were part of the record and are held as pointers to the methods associated with the object's type. 
+
(従来のレコードと同様に) オブジェクトの定義で宣言されるが、プロシージャと関数はレコードの一部であるかのように宣言でき、オブジェクトの型に関連付けられたメソッドへのポインタとして保持されるようになった。
  
For example, an object could contain an array of real values, together with a Method for calculating the average.
+
例えば、平均を計算するメソッドともに実数値の配列を保持するオブジェクトを仮定する。
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 118: Line 118:
 
     NumVal: Integer;
 
     NumVal: Integer;
 
     Values: Array [1..200] of Real;
 
     Values: Array [1..200] of Real;
     Function Mean: Real; { calculates the average value of the array }
+
     Function Mean: Real; { 配列の平均値を計算する }
 
   End;
 
   End;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Objects can ”inherit” fields and methods from ”parent” objects. This means that these fields and methods can be used as if they were included in the objects declared as a ”child” object.
+
「オブジェクト」はフィールドとメソッドを「親」オブジェクトから「継承」することができる。これはこれらのフィールとメソッドが、「子」として宣言されたオブジェクトに含まれているかのように、用いることができることを意味する。
  
Furthermore, a concept of visibility is introduced: fields, procedures and functions can be declared
+
さらに、視認性の観念は、フィールド、プロシージャ、関数がpublic、protected、privateとして宣言することを可能とした。デフォルトではフィールドとメソッドはpublicで、現在のユニットの外側へエクスポートできる。Protectされたフィールドやメソッドは現在の祖先オブジェクトから派生したオブジェクトにとってのみ利用可能である。Privateで宣言されたフィールドや、メソッドは現在のユニットでのみアクセスが可能である:そのスコープは現在のユニットの実装に限られている。
as public, protected or private. By default, fields and methods are public, and can be exported outside the
 
current unit. Protected fields or methods are available only to objects descended from the current ancestor object. Fields or methods that are declared private are only accessible in the current unit:
 
their scope is limited to the implementation of the current unit.
 
  
 
=== クラス ===
 
=== クラス ===
Objects are not used very often by themselves in Free Pascal and Lazarus; instead, Classes are used very widely. A Class is defined in almost the same way as an Object, but is a pointer to an Object rather than the Object itself. Technically, this means that the Class is allocated on the Heap of a program, whereas the Object is allocated on the Stack.
+
オブジェクトはFree PascalとLazarusではそう頻繁には用いられない。むしろ、クラス(Class)は広く用いられる。クラスはほとんどオブジェクトと同様に宣言されるが、オブジェクト自身というよりはオブジェクトに対するポインタである。技術的には、これはプログラムのヒープに割り当てられるが、オブジェクトはスタックに割り当てられる。
  
Here is a simple example of a typical Class declaration:
+
これはクラス宣言の典型的な例である:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
 
{-------------------------------------------}
 
{-------------------------------------------}
{ Example of Class declaration from the LCL }
+
{       LCLからのクラス宣言の例            }
 
{-------------------------------------------}
 
{-------------------------------------------}
 
   TPen = class(TFPCustomPen)
 
   TPen = class(TFPCustomPen)
Line 172: Line 169:
 
   end;</syntaxhighlight>
 
   end;</syntaxhighlight>
  
 
+
このクラスは他の'''parent(親)'''もしくは'''ancestor(祖先)'''クラス(''TFPCustomPen'')のインスタンスとして宣言されていることに注意すること。その祖先から、すべてのプロパティとメソッドを'''inherit(継承)'''している。このクラスはそれ自身のフィールドを有しており、以下にグループ化されている。
Note that this class is defined as an instance of another '''parent''' or '''ancestor''' class (''TFPCustomPen'') from which it '''inherits''' all its properties and methods. It has some fields of its own, grouped under
+
*'''private''' - これはここで定義されたアイテムが、同じプログラムユニットの他のクラスもしくはプロシージャ/関数からのみ用いるあるいは、見ることができる(この例では、''Graphics''から、そのように他のクラスのいずれ、例えば、同じユニットの''TBitMap''''TPicture''などでもそれらを使うことができる)ことを意味する。それらは本質的にはローカル変数(例えば''FColor''''FPenHandleCached'')もしくは、ローカルで用いられるメソッド(''GetHandle''''SetHandle'')だが、'''protected'''もしくは'''public'''節で宣言されたアイテムで用いる、あるいは参照されることができる。
*'''private''' - this means that items defined here are only available or visible to other classes or procedures/function defined within the same program unit (this example is from ''Graphics'', so any of the other classes such as ''TBitMap'', ''TPicture'' etc in the same unit can use them). They are essentially local variables (eg ''FColor'', ''FPenHandleCached'') or locally used methods (''GetHandle'', ''SetHandle'') but can be used or referred to in items declared in the '''protected''' or '''public''' sections.
+
*'''protected''' - これはここで定義されたアイテムが、この'''祖先'''クラスから派生したクラスにとってのみ用いる、あるいは見ることができることを意味し、そのプロパティとメソッドを継承する。
*'''protected''' - this means that items defined here are only available or visible to classes that are descended from this '''ancestor''' class, and inherit its properties or methods
+
*'''public''' - これはここで定義されたアイテムが[[Glossary#Uses | Uses]]句の現在のユニットを含むどのプログラミングユニットからも利用できることを意味する。
*'''public''' - this means that items defined here are available to any programming unit that includes the current unit in its [[Glossary#Uses | Uses]] clause
+
*'''published''' - '''public'''節と同様であるが、コンパイラが、これらのクラスの自動的ストリーミングにとって必要な型情報も生成する。パブリッシュされたアイテムはLazarusのオブジェクトインスペクタに通常現れる。もし、パブリッシュされたリストがない場合、オブジェクトインスペクタには、いつもすべての'''public'''フィールドが現れる。
*'''published''' - is the same as a '''public''' section, but the compiler also generates type information that is needed for automatic streaming of these classes. Often the list of published items appear in the Object Inspector of Lazarus; if there is no '''published''' list, all the '''public''' fields usually appear in the Object Inspector.
 
  
 
=== メソッド ===
 
=== メソッド ===
A method is just like a standard procedure or function, but can have some additional '''directives'''.
 
  
Some of the methods defined above are labelled with the directive '''virtual'''; others are labelled with the '''override''' directive.
+
メソッドは標準のプロシージャ、もしくは関数に似ているが、いくつかの'''指令(directive)'''を持つ。
*'''virtual''' means that the type or actual instance of a method is not known at compile-time, but is selected at run-time depending on what sub-program actually calls the method. It could be considered a place-holder in the definition of the class.
+
上記で定義されているメソッドのいくつかは指令、'''virtual'''、他は'''override'''指令が付けられている。
*'''override''' means that at run-time the locally given definition can take the place of a definition inherited from an ancestor class, particularly if it was '''virtual'''. If you particularly want to use the method defined in the ancestor class, it is sometimes necessary to call it specifically with the '''inherited''' clause.
+
* '''virtual''' はこのメソッドの型、もしくは実際のインスタンスがコンパイル時に知られていないことを意味するが、何のサブプログラムが実際にこのメソッドを呼ぶかによって、実行時に選択される。これはクラスの定義において場所取りとして、考えることができる。
 +
*'''override'''は実行時のローカルな定義が、特にもしそれが'''実質的(virtual)'''であるならば、派生クラスから継承された定義の場所をとってかわることを意味する。もし、特に、祖先クラスで定義されたメソッドを使いたいときは、特異的に'''継承された'''句とともに呼ぶ必要がある。
  
Methods with no virtual or override directive are '''static''' methods (the usual kind in Pascal). Those with a virtual or override directive are '''dynamic'''.
+
Virtualあるいはoverride指令のないメソッドは'''静的(static)'''メソッド(Pascalにおける通常の種類)である。Virtualあるいはoverride指令は'''動的(dynamic)'''である。
  
Special instances of methods are:
+
メソッドの特定のインスタンスは:
*'''create''' - a '''constructor''' for a class, which takes care of allocating memory, collecting together all the information needed and configuring/initializing the various properties.
+
*'''create''' - メモリの割り当て、全ての必要かつ、様々なプロパティを設定/初期化するためにな情報を一緒に集める、'''コンストラクタ(constructor)'''である。
*'''destroy''' - a '''destructor''' for a class, which removes all the parts of the class from the system in an orderly and logical way, and returns all its resources for the system to re-use.
+
*'''destroy''' - 順に従い、論理的にシステムからクラスのすべての部品を取り除く、そして再使用するためシステムにそのリソースを返す'''ディストラクタ(distructor)'''である。
  
 
=== プロパティ ===
 
=== プロパティ ===
  
Properties are just like ordinary fields in a conventional Pascal record, but they can have '''read''' and/or '''write''' specifiers.
+
プロパティは従来的なPascalにおける通常のフィールドに似ているが、'''読み取り(read)'''あるいは/および'''書き込み(write)'''指示子を持つ。
*'''read''' specifier is a field, or a function that returns a result of the correct type for the property. In the example above, the property ''Color'' has a read specifier ''FColor'', which is a local variable containing the value to be used. If a property has a '''read''' but no '''write''' specifier, it is read-only.
+
* '''read'''指示子はプロパティの正しい結果を返すフィールド、あるいは関数である。上記の例では、プロパティ''Color''は使われる値を保持しているローカル変数である、読み取り指示子''FColor''を持っている。もしプロパティが'''read'''を持ち、'''write'''指示子を持っていないなら、それは読み取り専用(read-only)である。
*'''write''' specifier is a field, or a procedure that will store the value of the property in a specific location. In the example above, ''Color'' has a write specifier ''SetColor'' that is a procedure (defined in the  '''protected''' section) for writing the color value to some specified location. If a property has a '''write''' but no '''read''' specifier, it is write-only.
+
* '''write'''指示子は特定の場所の値を保持する、フィールドもしくはプロシージャである。上の例では''Color''は特定の場所に対する色を書き込むためのプロシージャ('''protected'''節で宣言されている)である書き込み指示子、''SetColor''を持っている。もしプロパティが'''write'''を持ち、'''read'''を持たないなら、書き込み専用(write-only)である。
*'''default''' - note that it is possible to set a '''default''' value for a property. For example, ''Color'' here is given the default value ''clBlack'', or black, at the time of creation. It could subsequently be given a different value, by a programming assignment statement, or in the Object Inspector.
+
* '''default''' - '''default'''値をプロパティに持たせることが可能なことに注意すること。例えば、ここで''Color''が生成時にデフォルト値''clBlack''、もしくは黒を持っている。それは引き続き異なった値が、プログラムの割り当てまたは、オブジェクトインスペクタにより、与えられうる。
*'''index''' specifier is an  integer that the '''read''' or '''write''' methods, shared between properties, can use to identify which property is desired. Note that if '''index''' is used the '''read''' or '''write''' specifiers must be a function or a procedure respectively and cannot be a normal field/variable.
+
* '''index'''指示子は、プロパティ間で共有される、'''read''' もしくは '''write'''メソッドが、どのプロパティが望ましいか特定するために用いることのできる整数値である。もし、'''index''''''read''' もしくは '''write'''で用いられているなら、指示子はそれぞれ、関数、もしくはプロシージャなければならず、通常のフィールド/値たりえないことに注意すること。
 +
 
  
 
====例====
 
====例====
Line 217: Line 214:
 
     procedure SetListProp(AIndex: Integer; AValue: String);
 
     procedure SetListProp(AIndex: Integer; AValue: String);
 
   public
 
   public
     // this type of property may not be in the published section of a class
+
     // プロパティのこの型はクラスのpublishedセクションにはないだろう
 
     property ListProp[AIndex: Integer]: String read GetListProp write SetListProp;  
 
     property ListProp[AIndex: Integer]: String read GetListProp write SetListProp;  
 
   end;
 
   end;
Line 233: Line 230:
 
     property Value3: Integer index 3 read GetValue write SetValue;
 
     property Value3: Integer index 3 read GetValue write SetValue;
 
     property Value4: Integer index 4 read GetValue write SetValue;
 
     property Value4: Integer index 4 read GetValue write SetValue;
     // index may be a const or a number or you can even use an enumerated type
+
     // インデクスは定数か、数値、あるいは型を列挙することもできる
     // for example:
+
     // 例えば:
 
     // property Value: Integer index ord(seSomeEnum) read SomeFunction write SomeProcedure;
 
     // property Value: Integer index ord(seSomeEnum) read SomeFunction write SomeProcedure;
 
   end;
 
   end;
Line 241: Line 238:
 
== Free Pascal 言語拡張 ==
 
== Free Pascal 言語拡張 ==
  
FPC includes several language extensions to its "standard" Pascal syntax to support object oriented programming. 
+
FPCはオブジェクト指向プログラミングをサポートするためにその「標準」Pascal文法にいくつかの言語拡張を含んでいる。
  
* Objects    (chapter 5)   [[Programming Using Objects]]
+
* オブジェクト  (5 ) [[Programming Using Objects]]
* Classes    (chapter 6)  [[Programming Using Classes]]
+
* クラス        (6 )  [[Programming Using Classes/ja]]
* Interfaces (chapter 7)  [[Programming Using Interfaces]]
+
* インタフェース (7 )  [[Programming Using Interfaces]]
* Generics   (chapter 8)  [[Programming Using Generics]]
+
* ジェネリクス   (8 )  [[Programming Using Generics]]
  
These extensions are described in the indicated chapters of the FPC Language Reference Guide: http://www.freepascal.org/docs.var. Links to tutorial pages for each concept are included above as well. The Language Reference Guide includes syntax diagrams and further details not contained in this introductory tutorial.   Of the four language features listed above, '''Objects''' and '''Classes''' form the basis of object oriented programming (OOP) in FPC and Lazarus.  For those new to OOP, the '''Objects''' section includes more introductory concepts and the '''Classes''' section minimizes repetition by emphasizing the similarities and differences to the '''Objects''' syntax.  In general, the '''Classes''' implementation seems to be more widely in use including Delphi  Lazarus developers.  Often the word "objects" is used to refer to what is actually a "class" in the '''Classes''' dialect of OOP in FPC.  These documents will be worded to minimize any terminology confusion, but outside of this document, the term "object" oftentimes refers to objects created from a '''Class'''.  In fact, the FPC run time library (RTL) includes a class library with a base '''class''' called ''TObject''.
+
これらの拡張はFPC Language Reference Guide http://www.freepascal.org/docs.var.(訳注: このリンクは無効であるFPCのリファレンスに対するURLは https://www.freepascal.org/docs-html/current/ref/ref.html である)で述べられており、それぞれの概念に対するチュートリアルへのリンクもある。Language Reference Guideはこの概要チュートリアルには含まれない文法便覧とさらなる細部を含んでいる。上記には4つの言語仕様が含まれており、[https://www.freepascal.org/docs-html/current/ref/refch5.html#x59-790005 '''Objects''']と[https://www.freepascal.org/docs-html/current/ref/refch6.html#x69-930006 '''Classes''']はFPCとLazarusにおける、オブジェクト指向プログラミング (OOP)の基礎を成している。OOP初心者にとって、'''Objects'''セクションはより概説的なセクションで、'''Classes'''セクションは'''Objects'''文法に対する類似性と相違性を強調することで、反復を最小限にしている。一般的に '''Classes''' 実装はDelphi、Lazarus開発者により広く用いられている。FPCではOOPの '''Classes''' 方言で、何が実際「class」なのかに言及することに「object」がよく使われている。これらのドキュメントは命名上の混乱を最小限にするために記述されているが、このドキュメント以外では、通常、 '''Class''' から作られるオブジェクトに用語「object」が用いられている。実際、FPCランタイムライブラリ(RTL)''TObject'' と呼ばれる基底 '''class''' を持つクラスライブラリを含んでいる。
  
Users familiar with the older Turbo Pascal OOP implementation may initially want to skip the section on Classes since the Objects implementation is based on the older Turbo Pascal dialect.  The section on  '''Classes''' should be familiar to Delphi users since it is based on Delphi syntax.  Be aware that some of the writeup in the '''Classes''' section may refer to concepts from the '''Objects''' section.  For Macintosh developers familiar with the various Apple, THINK and MPW Object Pascal dialects, neither the FPC Objects or Classes dialects provide a direct migration path. As of March 2009, there are discussions on the Mac Pascal Mailing list about potentially providing some compiler support (new syntax) for accessing Apple's Objective C / Cocoa framework.
+
古いTurbo Pascal OOP実装に慣れているユーザーはオブジェクト実装が古いTurbo Pascal方言に基づいているため、Classesセクションを初めは飛ばしたいかもしれない。'''Classes'''セクションはDelphi文法に基づいているため、Delphiユーザーにはなじみがあるはずだ。'''Classes'''セクションの書き方は'''Objects'''セクションからの概念を参照しているかもしれないことに注意すること。様々なApple、THINK、MPW Object Pascal方言になじみのあるマッキントッシュ開発者にとって、FPC ObjectsもしくはClasses方言のいずれも直接的な移行パスとならないだろう。2009年 3月時点では、Mac PascalメーリングリストではAppleのObjective C / Cocoa フレームワークにアクセスするためにあるコンパイラサポート(新しい文法)を提供する可能性が議論されている。
  
=== オブジェクト指向 Pascal一般的な概念===
+
=== オブジェクト指向 Pascal 一般的な概念===
  
OOP provides different ways to manage and encapsulate data and to manage program flow compared with other available programming language features and constructs.  OOP often lends itself to modeling certain applications such as Graphic User Interfaces (GUI's) and physical systems in a more natural feeling manner.  However OOP is not appropriate for all applications.  Program control is not as explicit as the more basic Pascal procedural constructs.  To obtain the most benefit from OOP, understanding of large class libraries is often required which can entail a steep learning curve.  Maintaining large OOP application code has its advantages and disadvantages compared to maintaining strictly procedural code.    There are many sources for learning OO analysis, design and programming techniques which are beyond the scope of this guide. 
+
OOPは利用可能な他の言語仕様と設計に比べ、データの取り扱いとカプセル化とプログラムフローを取り扱う異なる方法を提供する。OOP は多くの場合、グラフィック ユーザー インターフェイス (GUI) や物理システムなどの特定のアプリケーションを、より自然な感覚でモデル化するのに役立つ。しかし、OOPはすべてのアプリケーションに適切ではない。プログラムコントロールはより基本的なPascal手続き的構造ほど明示的ではない。OOPから最も恩恵を受けるためには、学習曲線が急であることを通常必要とする、大きなクラスライブラリの理解が必須とされる。厳格な手続き的コードをメンテナンスすることに比べ、大規模なOOPアプリケーションコードをメンテナンスすることは、その利点と、欠点がある。OO分析、設計とプログラミング技法に対する豊富な学習教材があるが、それらは本稿の範疇を超えてしまう。
  
There are numerous programming languages which incorporate OOP features as extensions or the basis of their language.  As such, there are many different terms for describing OO concepts.  Even within FPC, some of the terminology overlaps.  In general, OOP usually consists of the concept of a programming object (or information unit) which explicitly combines and encapsulates a related set of data and procedures which act on the data.  This data is usually persistent during program execution but with mechanisms to reduce some of the problems inherent in declaring global variables.  In addition, OOP languages enable objects to be incrementally modified and/or extended based on previously defined objects.  This feature is usually referred to by the terms ''inheritance'' and ''polymorphism''.    Many OOP languages use  the terms ''method'' or ''message'' referring to procedures which belong to an object.  Much of the power of OOP is realized by late (run time) dynamic binding of methods rather than compile binding.  This dynamic binding of methods is similar to using procedural variables and procedural parameters but with greater syntactic cohesion, encapsulation with the data it is related to and also inheritance of behavior of previously defined methods.  The following wiki pages provide a starting point for discovering more about analysis, design and programming in an object orient manner.
+
拡張、あるいはその言語の基本として、OOPフィーチャを取り込んだ多くのプログラミング言語が存在する。このように、OOコンセプトを記述するために多くの異なる用語がある。FPCですら、いくつかの命名上の重複がある。一般的に、OOPはデータ上で機能するデータとプロシージャの関連したセットを明示的に組み合わせ、カプセル化するプログラミングオブジェクト(もしくは、情報ユニット)の概念よりなっている。データは通常、プログラムの実行中に永続的だが、グローバル変数の宣言に固有の問題を軽減するメカニズムが備わっている。さらに、OOP 言語を使用すると、以前に定義されたオブジェクトに基づいてオブジェクトを段階的に変更および/または拡張できる。 この機能は通常、''継承''および''ポリモーフィズム''という用語で呼ばれる。多くのOOP言語は、1つのオブジェクトに属する、プロシージャを称するのに、''メソッド'' もしくは ''メッセージ''用語を用いる。OOPの力の源泉はコンパイルバインディングよりも、メソッドの遅い(実行時)、動的なバインディングによって、認識される。このメソッドの動的なバインディングは、プロシージャ変数とプロシージャ パラメータの使用に似ているが、構文の凝集性が高く、関連するデータとのカプセル化が行われ、以前に定義されたメソッドの動作も継承される。次の Wiki ページは、オブジェクト指向の方法での分析、設計、プログラミングについてさらに詳しく知るための出発点を提供する。
  
 
== さらなる情報 ==
 
== さらなる情報 ==
  
This has only scratched the surface of the topic. For more details, readers are strongly recommended to read the [http://lazarus-ccr.sourceforge.net/fpcdoc/ref/ref.html Free Pascal] manuals, especially Chapters 5 ('''Objects''') and 6 ('''Classes''')
+
これは、この話題についてほんの触りを述べたに過ぎない。より詳細には、[http://lazarus-ccr.sourceforge.net/fpcdoc/ref/ref.html Free Pascal]マニュアルの特に、5章('''Objects''')と6章('''Classes''')を読むことを強く推奨する。
  
Borland was also kind enough to release the Object Oriented Programming chapter from the original Turbo Pascal manuals in PDF form. This chapter is from when Borland introduced this new language feature into Turbo Pascal. The chapter might be old, but the OOP theory is still very relevant today. You can download a copy from the following [http://geldenhuys.co.uk/articles/ link] under the "Other" category.
+
ボーランドはまた、寛大にもPDF媒体で、オリジナルのTurbo Pascalマニュアルから、オブジェクト指向プログラミングの章を解放していた。この章ではこの言語仕様をボーランドがTurbo Pascalに導入したときからが書かれている。これは古いかもしれないが、OOPの理論は今日でも非常に関連性がある。[http://geldenhuys.co.uk/articles/ Link]の「その他」のカテゴリから、ダウンロードできる。
  
 
== 以下も参照のこと ==
 
== 以下も参照のこと ==
  
* [[Programming Using Classes]]
+
* [[Programming Using Classes/ja]]
 
* [[Free Pascal videos|Free Pascal video tutorials]]
 
* [[Free Pascal videos|Free Pascal video tutorials]]
 
* [[Lazarus videos|Lazarus video tutorials]]
 
* [[Lazarus videos|Lazarus video tutorials]]

Latest revision as of 12:50, 3 April 2024

English (en) español (es) français (fr) magyar (hu) italiano (it) 日本語 (ja) македонски (mk) русский (ru) 中文(中国大陆)‎ (zh_CN) 中文(台灣)‎ (zh_TW)

概要

Pascal に関する優れたチュートリアルは数多くあるが、このチュートリアルは初心者をさらに Turbo Pascal,、DelphiFree Pascal / Lazarusにより提供される標準 Pascalの拡張である、 オブジェクト指向プログラミングを深く理解することを目的としている。

オブジェクトは標準パスカルの構造のレコード構造の拡張である。

標準のテキストベースのPascalプログラミングは、1つのことを非常に巧みにこなす伝統的なUnixアプリケーションのようなアプリケーションを作るうえではよいものである。

プログラムが行う「1つのこと」は非常に複雑なアクションであるかもしれないし、ユーザーに複数のメニュー駆動型オプションを提供するかもしれない。しかし、本質的には、ユーザーがキーボードで入力するコマンドに従い、そのレスポンスを端末やプリンターに表示することに制限されている。

グラフィカルユーザーインタフェース (GUI)を提供するために、ある種のオブジェクト指向プログラミングメソッド(C言語やその派生、もしくはVisual Basic、例えば Lazarusを用いる、あるいは用いない Free PascalのようなPascalの派生 OO)が用いられるのは通常のことである。

GUIでは、ユーザーには以下のような様々な、道具やアクションに紐づけられた ウイジェットのセットからなる、整頓された多くの画像が示される。

  • メニューから選択する
  • ファイルを開く、保存する
  • インターネットに接続する
  • 算術演算を行う

など。

ユーザーは、画面上でマウスまたはその他のポインター/選択ツールを移動し、マウス ボタンのクリックまたはキーの押下に応じて実行されるアクションを選択することを期待している。

複雑なグラフィカル ユーザー インターフェイスを処理するシステムは、標準の Pascal またはその他のほぼすべてのプログラミング言語で作成できるものの、それぞれのグラフィカルオブジェクトが、画面上で、すべてのプロパティとプロシージャ、共通の構造とともに使用法が結びつけられた関数を持つことのできる、オブジェクト指向システムを用いるほうがはるかにたやすい。

オブジェクト - 現実世界の相似

病院や診療所で採取された血液サンプルの例を考えてみよう。

血液サンプル

物理的なサンプルは文字通り「実体」- objectであり、情報、ドキュメント、他の多くの物理的なオブジェクトが紐づけられている。

  • サンプルの入った試験管、の型は医師が望む試験の種類を規定する
  • ローカルルール (または メソッド, スタンダードオペレーティングプロシージャ) は看護師や技師にサンプルを集める指示を出す
    • どの種類の試験管が用いられるべきか
    • サンプルがどのように扱われるべきか
    • 検査室に運ばれるまでどのように保存されるべきか
  • ラベルは以下の細目について記載されている
    • サンプルの識別記号番号
    • 患者の氏名と誕生日
    • 採取した日付と時刻
    • 必要とする検査
  • 要望文書 それはサンプルとともに検査室へもたらされ、指示には
    • サンプルの識別記号番号
    • 指示した医師のID
    • 医師が望んだ検査
    • 患者のより詳しい情報
    • 確認が求められている、可能性がある診断

患者のカルテには、医師がしかるべき時に期待する結果を確認させる、要望文書のコピーが加えられる。

  • 検査室では - ローカルメソッドが以下を規定する
    • どのようにサンプルが分析されるか
    • どの機器を用いるか
    • どのようにその機器が補正され、運転されるべきか
    • どのように結果が保存され、形式が整えられるか
    • 医師に結果を報告すること

実際の 結果 が医師の診断を助けるために記録され、患者のカルテに検査結果のコピーが挟まれる。

物理的なサンプルは参照、確認、あるいはさらなる検査のために保存されるか、流しに捨てられる、あるいは焼却処分される。これを述べた方法があるだろう。

医師はサンプルが採取されるたびに、いちいちすべての細目と指示を書き込む必要はなく、検査室でそのサンプルがどのように検査されるかほとんど知らないだろう。この様々な課程の細目は、以前のサンプル採取と分析から継承され、全体の結果に対する、一定の計画、血液サンプルに対して考えらえる、ドキュメントとデータ、その基礎のメソッドを複合がオブジェクトである。 医師の考えでは、血液サンプルはその結果とほぼ同じ実体とみなされ、看護師や技師にとっては、サンプル、チューブ、ラベル、および保管状態が再び単一の実体を成す。

別の例 - 自動車

もし、血を見るのが嫌ならば、同様の理屈が車庫から、修理場へ運ばれる自動車にも適用できる。 それは以下よりなっているだろう:

  • 自動車自体
  • 所有者によって保存されている、登録証、車両ナンバー(車両ナンバープレートを含む)、保険証、購入の領収書、部品、修理などの書類
  • 燃料消費履歴
  • その自動車を使うことのできる運転者、およびその免許書
  • 修理場でのサービス記録
  • 定期点検とメンテナンスの方法(メソッド)と手順(プロシージャ)を追う書類
  • 非定期点検、修理を追うメソッド
  • 顧客の支払い情報

プログラミング例

こんな実社会の事例に没頭するのはもうたくさんだ! 主題のObject Pascalでのプログラミングに進もう。

Free Pascal/Lazarusでいくつかのコントロールを持つ簡単なフォームを作ることを考える。

ObjectInspector-TForm-ja.png
BlankForm-ja.png

Lazarus IDEを起動すると、プログラマにはフォーム設計の様々なコントロールや、オブジェクトを置くことを促す、空のテンプレートがもたらされる。

あらかじめ作られたフォームがすでにオブジェクトであるとこに注意すること。それは位置(上辺、左)、大きさ(高さ、幅)、色、テキストを加えるときのデフォルトのフォントなどのプロパティを持つ。


もしボタンコントロール(TButton型)がフォームに置かれると、それは、オブジェクトインスペクタで検討できるそれ自身の一連のプロパティを持つ。

そのプロパティのいくつかはフォームと似たような名前を持っている。これはある共通のその派生クラスによって、どのようにそのプロパティが定義され、扱われるかをレイアウトする祖先クラスから継承されたプロパティであることが理由である。

プロパティ同様に、オブジェクトインスペクタはアプリケーションがどのように、例えばマウスボタンクリック(OnClick)もしくは位置や、大きさ、他のプロパティを変更(OnChange)したときに、それらを扱うかを指示するメソッドであるイベントハンドラにアクセスするイベント(Events)という名前のタブを持つ。

フォーム上の物理的な画像であるボタンは、そのプロパティとイベントハンドラと相まって、パスカルでは単一の実体オブジェクト(Object)とみなされる。

ObjectInspector-TButton-ja.png
FormWithButton-ja.png
Source FormWithButton1-ja.png

標準パスカルに対するオブジェクト指向拡張

Pascalのレコード構造はオブジェクトを定義することで拡張された。

オブジェクト

オブジェクトは特別な種類のレコードである。 レコードには、次のすべてのフィールドが含まれる。 (従来のレコードと同様に) オブジェクトの定義で宣言されるが、プロシージャと関数はレコードの一部であるかのように宣言でき、オブジェクトの型に関連付けられたメソッドへのポインタとして保持されるようになった。

例えば、平均を計算するメソッドともに実数値の配列を保持するオブジェクトを仮定する。

Type
  Average = Object
    NumVal: Integer;
    Values: Array [1..200] of Real;
    Function Mean: Real; { 配列の平均値を計算する }
  End;

「オブジェクト」はフィールドとメソッドを「親」オブジェクトから「継承」することができる。これはこれらのフィールとメソッドが、「子」として宣言されたオブジェクトに含まれているかのように、用いることができることを意味する。

さらに、視認性の観念は、フィールド、プロシージャ、関数がpublic、protected、privateとして宣言することを可能とした。デフォルトではフィールドとメソッドはpublicで、現在のユニットの外側へエクスポートできる。Protectされたフィールドやメソッドは現在の祖先オブジェクトから派生したオブジェクトにとってのみ利用可能である。Privateで宣言されたフィールドや、メソッドは現在のユニットでのみアクセスが可能である:そのスコープは現在のユニットの実装に限られている。

クラス

オブジェクトはFree PascalとLazarusではそう頻繁には用いられない。むしろ、クラス(Class)は広く用いられる。クラスはほとんどオブジェクトと同様に宣言されるが、オブジェクト自身というよりはオブジェクトに対するポインタである。技術的には、これはプログラムのヒープに割り当てられるが、オブジェクトはスタックに割り当てられる。

これはクラス宣言の典型的な例である:

{-------------------------------------------}
{        LCLからのクラス宣言の例            }
{-------------------------------------------}
  TPen = class(TFPCustomPen)
  private
    FColor: TColor;
    FPenHandleCached: boolean;
    FReference: TWSPenReference;
    procedure FreeReference;
    function GetHandle: HPEN;
    function GetReference: TWSPenReference;
    procedure ReferenceNeeded;
    procedure SetHandle(const Value: HPEN);
  protected
    procedure DoAllocateResources; override;
    procedure DoDeAllocateResources; override;
    procedure DoCopyProps(From: TFPCanvasHelper); override;
    procedure SetColor
         (const NewColor: TColor; const NewFPColor: TFPColor); virtual;
    procedure SetFPColor(const AValue: TFPColor); override;
    procedure SetColor(Value: TColor);
    procedure SetMode(Value: TPenMode); override;
    procedure SetStyle(Value: TPenStyle); override;
    procedure SetWidth(value: Integer); override;
  public
    constructor Create; override;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
    property Handle: HPEN read GetHandle write SetHandle; deprecated;
    property Reference: TWSPenReference read GetReference;
  published
    property Color: TColor read FColor write SetColor default clBlack;
    property Mode default pmCopy;
    property Style default psSolid;
    property Width default 1;
  end;

このクラスは他のparent(親)もしくはancestor(祖先)クラス(TFPCustomPen)のインスタンスとして宣言されていることに注意すること。その祖先から、すべてのプロパティとメソッドをinherit(継承)している。このクラスはそれ自身のフィールドを有しており、以下にグループ化されている。

  • private - これはここで定義されたアイテムが、同じプログラムユニットの他のクラスもしくはプロシージャ/関数からのみ用いるあるいは、見ることができる(この例では、Graphicsから、そのように他のクラスのいずれ、例えば、同じユニットのTBitMapTPictureなどでもそれらを使うことができる)ことを意味する。それらは本質的にはローカル変数(例えばFColorFPenHandleCached)もしくは、ローカルで用いられるメソッド(GetHandleSetHandle)だが、protectedもしくはpublic節で宣言されたアイテムで用いる、あるいは参照されることができる。
  • protected - これはここで定義されたアイテムが、この祖先クラスから派生したクラスにとってのみ用いる、あるいは見ることができることを意味し、そのプロパティとメソッドを継承する。
  • public - これはここで定義されたアイテムが Uses句の現在のユニットを含むどのプログラミングユニットからも利用できることを意味する。
  • published - はpublic節と同様であるが、コンパイラが、これらのクラスの自動的ストリーミングにとって必要な型情報も生成する。パブリッシュされたアイテムはLazarusのオブジェクトインスペクタに通常現れる。もし、パブリッシュされたリストがない場合、オブジェクトインスペクタには、いつもすべてのpublicフィールドが現れる。

メソッド

メソッドは標準のプロシージャ、もしくは関数に似ているが、いくつかの指令(directive)を持つ。 上記で定義されているメソッドのいくつかは指令、virtual、他はoverride指令が付けられている。

  • virtual はこのメソッドの型、もしくは実際のインスタンスがコンパイル時に知られていないことを意味するが、何のサブプログラムが実際にこのメソッドを呼ぶかによって、実行時に選択される。これはクラスの定義において場所取りとして、考えることができる。
  • overrideは実行時のローカルな定義が、特にもしそれが実質的(virtual)であるならば、派生クラスから継承された定義の場所をとってかわることを意味する。もし、特に、祖先クラスで定義されたメソッドを使いたいときは、特異的に継承された句とともに呼ぶ必要がある。

Virtualあるいはoverride指令のないメソッドは静的(static)メソッド(Pascalにおける通常の種類)である。Virtualあるいはoverride指令は動的(dynamic)である。

メソッドの特定のインスタンスは:

  • create - メモリの割り当て、全ての必要かつ、様々なプロパティを設定/初期化するためにな情報を一緒に集める、コンストラクタ(constructor)である。
  • destroy - 順に従い、論理的にシステムからクラスのすべての部品を取り除く、そして再使用するためシステムにそのリソースを返すディストラクタ(distructor)である。

プロパティ

プロパティは従来的なPascalにおける通常のフィールドに似ているが、読み取り(read)あるいは/および書き込み(write)指示子を持つ。

  • read指示子はプロパティの正しい結果を返すフィールド、あるいは関数である。上記の例では、プロパティColorは使われる値を保持しているローカル変数である、読み取り指示子FColorを持っている。もしプロパティがreadを持ち、write指示子を持っていないなら、それは読み取り専用(read-only)である。
  • write指示子は特定の場所の値を保持する、フィールドもしくはプロシージャである。上の例ではColorは特定の場所に対する色を書き込むためのプロシージャ(protected節で宣言されている)である書き込み指示子、SetColorを持っている。もしプロパティがwriteを持ち、readを持たないなら、書き込み専用(write-only)である。
  • default - default値をプロパティに持たせることが可能なことに注意すること。例えば、ここでColorが生成時にデフォルト値clBlack、もしくは黒を持っている。それは引き続き異なった値が、プログラムの割り当てまたは、オブジェクトインスペクタにより、与えられうる。
  • index指示子は、プロパティ間で共有される、read もしくは writeメソッドが、どのプロパティが望ましいか特定するために用いることのできる整数値である。もし、indexread もしくは writeで用いられているなら、指示子はそれぞれ、関数、もしくはプロシージャなければならず、通常のフィールド/値たりえないことに注意すること。


  TFooClass = class
  private
    FIntProp: Integer;
  public
    property IntProp: Integer read FIntProp write FIntProp;
  end;
  TFooClass = class  
  private
    function GetListProp(AIndex: Integer): String;
    procedure SetListProp(AIndex: Integer; AValue: String);
  public
    // プロパティのこの型はクラスのpublishedセクションにはないだろう
    property ListProp[AIndex: Integer]: String read GetListProp write SetListProp; 
  end;
  TFooClass = class
  private
   function GetValue(const AIndex: Integer): Integer;
   procedure SetValue(const AIndex: Integer; AValue: Integer);
  public
    // note that the read and write methods are shared
    property Value1: Integer index 1 read GetValue write SetValue;
    property Value2: Integer index 2 read GetValue write SetValue;
    property Value3: Integer index 3 read GetValue write SetValue;
    property Value4: Integer index 4 read GetValue write SetValue;
    // インデクスは定数か、数値、あるいは型を列挙することもできる
    // 例えば:
    // property Value: Integer index ord(seSomeEnum) read SomeFunction write SomeProcedure;
  end;

Free Pascal 言語拡張

FPCはオブジェクト指向プログラミングをサポートするためにその「標準」Pascal文法にいくつかの言語拡張を含んでいる。

これらの拡張はFPC Language Reference Guide http://www.freepascal.org/docs.var.(訳注: このリンクは無効であるFPCのリファレンスに対するURLは https://www.freepascal.org/docs-html/current/ref/ref.html である)で述べられており、それぞれの概念に対するチュートリアルへのリンクもある。Language Reference Guideはこの概要チュートリアルには含まれない文法便覧とさらなる細部を含んでいる。上記には4つの言語仕様が含まれており、ObjectsClassesはFPCとLazarusにおける、オブジェクト指向プログラミング (OOP)の基礎を成している。OOP初心者にとって、Objectsセクションはより概説的なセクションで、ClassesセクションはObjects文法に対する類似性と相違性を強調することで、反復を最小限にしている。一般的に Classes 実装はDelphi、Lazarus開発者により広く用いられている。FPCではOOPの Classes 方言で、何が実際「class」なのかに言及することに「object」がよく使われている。これらのドキュメントは命名上の混乱を最小限にするために記述されているが、このドキュメント以外では、通常、 Class から作られるオブジェクトに用語「object」が用いられている。実際、FPCランタイムライブラリ(RTL)は TObject と呼ばれる基底 class を持つクラスライブラリを含んでいる。

古いTurbo Pascal OOP実装に慣れているユーザーはオブジェクト実装が古いTurbo Pascal方言に基づいているため、Classesセクションを初めは飛ばしたいかもしれない。ClassesセクションはDelphi文法に基づいているため、Delphiユーザーにはなじみがあるはずだ。Classesセクションの書き方はObjectsセクションからの概念を参照しているかもしれないことに注意すること。様々なApple、THINK、MPW Object Pascal方言になじみのあるマッキントッシュ開発者にとって、FPC ObjectsもしくはClasses方言のいずれも直接的な移行パスとならないだろう。2009年 3月時点では、Mac PascalメーリングリストではAppleのObjective C / Cocoa フレームワークにアクセスするためにあるコンパイラサポート(新しい文法)を提供する可能性が議論されている。

オブジェクト指向 Pascal 一般的な概念

OOPは利用可能な他の言語仕様と設計に比べ、データの取り扱いとカプセル化とプログラムフローを取り扱う異なる方法を提供する。OOP は多くの場合、グラフィック ユーザー インターフェイス (GUI) や物理システムなどの特定のアプリケーションを、より自然な感覚でモデル化するのに役立つ。しかし、OOPはすべてのアプリケーションに適切ではない。プログラムコントロールはより基本的なPascal手続き的構造ほど明示的ではない。OOPから最も恩恵を受けるためには、学習曲線が急であることを通常必要とする、大きなクラスライブラリの理解が必須とされる。厳格な手続き的コードをメンテナンスすることに比べ、大規模なOOPアプリケーションコードをメンテナンスすることは、その利点と、欠点がある。OO分析、設計とプログラミング技法に対する豊富な学習教材があるが、それらは本稿の範疇を超えてしまう。

拡張、あるいはその言語の基本として、OOPフィーチャを取り込んだ多くのプログラミング言語が存在する。このように、OOコンセプトを記述するために多くの異なる用語がある。FPCですら、いくつかの命名上の重複がある。一般的に、OOPはデータ上で機能するデータとプロシージャの関連したセットを明示的に組み合わせ、カプセル化するプログラミングオブジェクト(もしくは、情報ユニット)の概念よりなっている。データは通常、プログラムの実行中に永続的だが、グローバル変数の宣言に固有の問題を軽減するメカニズムが備わっている。さらに、OOP 言語を使用すると、以前に定義されたオブジェクトに基づいてオブジェクトを段階的に変更および/または拡張できる。 この機能は通常、継承およびポリモーフィズムという用語で呼ばれる。多くのOOP言語は、1つのオブジェクトに属する、プロシージャを称するのに、メソッド もしくは メッセージ用語を用いる。OOPの力の源泉はコンパイルバインディングよりも、メソッドの遅い(実行時)、動的なバインディングによって、認識される。このメソッドの動的なバインディングは、プロシージャ変数とプロシージャ パラメータの使用に似ているが、構文の凝集性が高く、関連するデータとのカプセル化が行われ、以前に定義されたメソッドの動作も継承される。次の Wiki ページは、オブジェクト指向の方法での分析、設計、プログラミングについてさらに詳しく知るための出発点を提供する。

さらなる情報

これは、この話題についてほんの触りを述べたに過ぎない。より詳細には、Free Pascalマニュアルの特に、5章(Objects)と6章(Classes)を読むことを強く推奨する。

ボーランドはまた、寛大にもPDF媒体で、オリジナルのTurbo Pascalマニュアルから、オブジェクト指向プログラミングの章を解放していた。この章ではこの言語仕様をボーランドがTurbo Pascalに導入したときからが書かれている。これは古いかもしれないが、OOPの理論は今日でも非常に関連性がある。Linkの「その他」のカテゴリから、ダウンロードできる。

以下も参照のこと

外部リンク