クラス
概要
4D ランゲージでは クラス の概念がサポートされています。 プログラミング言語では、クラスを利用することによって、属性やメソッドなどを持つ特定のオブジェクト種を定義することができます。
ユーザークラスが定義されていれば、そのクラスのオブジェクトをコード内で インスタンス化 することができます。 各オブジェクトは、それ自身が属するクラスのインスタンスです。 クラスは、別のクラスを 継承 することで、その 関数 を受け継ぐことができます。
4D におけるクラスモデルは JavaScript のクラスに類似しており、プロトタイプチェーンに基づきます。
たとえば、次のように Person
クラスを定義した場合:
//Class: Person.4dm
Class constructor($firstname : Text; $lastname : Text)
This.firstName:=$firstname
This.lastName:=$lastname
Function sayHello()->$welcome : Text
$welcome:="Hello "+This.firstName+" "+This.lastName
この "Person" のインスタンスをメソッド内で作成するには、以下のように書けます:
var $person : cs.Person //object of Person class
var $hello : Text
$person:=cs.Person.new("John";"Doe")
// $person:{firstName: "John"; lastName: "Doe" }
$hello:=$person.sayHello() //"Hello John Doe"
クラスの管理
クラス定義
4D においてユーザークラスとは、/Project/Sources/Classes/
フォルダーに保存された専用のメソッドファイル (.4dm) によって定義されます。 ファイル名がクラス名になります。
クラスを命名する際には、次のルールに留意してください:
- A class name must be compliant with property naming rules.
- 大文字と小文字が区別されること
- 競合防止のため、データベースのテーブルと同じ名前のクラスを作成するのは推奨されないこと
たとえば、"Polygon" という名前のクラスを定義するには、次のファイルを作成する必要があります:
- Project フォルダー
- Project
- Sources
- クラス
- Polygon.4dm
- クラス
- Sources
- Project
クラスの削除
既存のクラスを削除するには:
- ディスク上で "Classes" フォルダーより .4dm クラスファイルを削除します。
- 4D エクスプローラーでは、クラスを選択した状態で
をクリックするか、コンテキストメニューより 移動 > ゴミ箱 を選択します。
4D インターフェースの使用
ファイル メニューまたはエクスプローラーなど、4D インターフェースを介してクラスを作成した場合には、クラスファイルは自動的に適切な場所に保存されます。
ファイルメニューとツールバー
4D 開発の ファイル メニューまたはツールバーより 新規 > クラス... を選択することで、開いているプロジェクトにクラスファイルを新規作成することができます。
Ctrl+Shift+Alt+k ショートカットも使用できます。
エクスプローラー
エクスプローラーの メソッド ページにおいて、クラスは クラス カテゴリに分類されています。
クラスを新規作成するには次の方法があります:
- クラス カテゴリを選択し、
ボタンをクリックします。
- エクスプローラーウィンドウの下部にあるアクションメニュー、またはクラスグループのコンテキストメニューから 新規クラス... を選択します。
- エクスプローラーのホームページのコンテキストメニューより 新規 > クラス... を選択します。
クラスのコードサポート
In the various 4D windows (code editor, compiler, debugger, runtime explorer), class code is basically handled like a project method with some specificities:
- コードエディター:
- クラスは実行できません
- クラスメソッドはコードのブロックです
- オブジェクトメンバーに対する 定義に移動 操作はクラスの Function 宣言を探します。例: "$o.f()" の場合、"Function f" を見つけます。
- クラスのメソッド宣言に対する 参照箇所を検索 操作は、そのメソッドがオブジェクトメンバーとして使われている箇所を探します。例: "Function f" の場合 "$o.f()" を見つけます。
- ランタイムエクスプローラーおよびデバッガーにおいて、クラスメソッドは <ClassName> コンストラクターまたは <ClassName>.<FunctionName> 形式で表示されます。
クラスストア
定義されたクラスには、クラスストアよりアクセスすることができます。 クラスストアには次の二つが存在します:
cs
- ユーザークラスストア4D
- ビルトインクラスストア
cs
cs -> classStore
参照 | タイプ | 説明 | |
---|---|---|---|
classStore | object | <- | プロジェクトまたはコンポーネントのユーザークラスストア |
cs
コマンドは、カレントプロジェクトまたはコンポーネントのユーザークラスストアを返します。 これには、プロジェクトまたはコンポーネントにて 定義 されている、すべてのユーザークラスが含まれます。 デフォルトでは、 ORDAクラス のみ利用可能です。
例題
myClass
オブジェクトの新規インスタンスを作成するには、次のように書きます:
$instance:=cs.myClass.new()
4D
4D -> classStore
参照 | タイプ | 説明 | |
---|---|---|---|
classStore | object | <- | 4Dクラスストア |
4D
コマンドは、ビルトイン 4Dクラスのクラスストアを返します。 CryptoKey などの専用 API へのアクセスを提供します。
例題
CryptoKey
クラスに新規キーを作成するには、次のように書きます:
$key:=4D.CryptoKey.new(New object("type";"ECDSA";"curve";"prime256v1"))
Class オブジェクト
プロジェクトにおいてクラスが 定義 されていれば、それは 4Dランゲージ環境に読み込まれます。 クラスとは、それ自身が "Class" クラス のオブジェクトです。 Class オブジェクトは次のプロパティや関数を持ちます:
name
文字列superclass
オブジェクト (無い場合は null)new()
関数 (クラスオブジェクトをインスタンス化します)
In addition, a class object can reference a constructor
object (optional).
Class オブジェクトは 共有オブジェクト です。したがって、異なる 4Dプロセスから同時にアクセスすることができます。
Inheritance
If a class inherits from another class (i.e. the Class extends keyword is used in its definition), the parent class is its superclass
.
When 4D does not find a function or a property in a class, it searches it in its superclass
; if not found, 4D continues searching in the superclass of the superclass, and so on until there is no more superclass (all objects inherit from the "Object" superclass).
クラスキーワード
クラス定義内では、専用の 4Dキーワードが使用できます:
Function <Name>
to define class functions of the objects.Class constructor
to define the properties of the objects.Class extends <ClassName>
: 継承を定義します。
Function
シンタックス
Function <name>({$parameterName : type; ...}){->$parameterName : type}
// コード
Class functions are specific properties of the class. They are objects of the 4D.Function class.
クラス定義ファイルでは、Function
キーワードと関数名を使用して宣言をおこないます。 The function name must be compliant with property naming rules.
Tip: アンダースコア ("_") 文字で関数名を開始すると、その関数は 4Dコードエディターの自動補完機能から除外されます。 たとえば、
MyClass
にFunction _myPrivateFunction
を宣言した場合、コードエディターにおいて"cs.MyClass "
とタイプしても、この関数は候補として提示されません。
関数名のすぐ後に、名前とデータ型を指定して 引数 を宣言します (戻り値の宣言も可)。 たとえば:
Function computeArea($width : Integer; $height : Integer)->$area : Integer
クラスメソッド内でオブジェクトインスタンスを参照するには This
コマンドを使います。 たとえば:
Function setFullname($firstname : Text; $lastname : Text)
This.firstName:=$firstname
This.lastName:=$lastname
Function getFullname()->$fullname : Text
$fullname:=This.firstName+" "+Uppercase(This.lastName)
クラス関数の場合には、Current method name
コマンドは次を返します: "<ClassName>.<FunctionName>" (例: "MyClass.myMethod")。
アプリケーションのコード内では、クラス関数はオブジェクトインスタンスのメンバーメソッドとして呼び出され、<a href="#クラス関数の引数>引数 を受け取ることができます。 次のシンタックスがサポートされています:
()
演算子の使用 For example,myObject.methodName("hello")
- use of a "4D.Function" class member method:
Thread-safety warning: If a class function is not thread-safe and called by a method with the "Can be run in preemptive process" attribute: - the compiler does not generate any error (which is different compared to regular methods), - an error is thrown by 4D only at runtime.
Parameters
Function parameters are declared using the parameter name and the parameter type, separated by a colon. The parameter name must be compliant with property naming rules. 複数のパラメーター (およびその型) を宣言する場合は、それらをセミコロン (;) で区切ります。
Function add($x; $y : Variant; $z : Integer; $xy : Object)
パラメーターの型が宣言されていない場合には、
バリアント型
として定義されます。
関数の戻り値を宣言するには (任意)、入力パラメーターリストに矢印 (->) と戻り値の定義を追加します。 XPath: /ul[5]/li[2]/ClassName/ClassName/FunctionName/p[22] たとえば:
Function add($x : Variant; $y : Integer)->$result : Integer
戻り値は、コロン (:) 記号の後に戻り値のデータ型だけを指定して宣言することもできます。その場合は、自動的に $0 が使用されます。 たとえば:
Function add($x : Variant; $y : Integer): Integer
$0:=$x+$y
メソッド内の引数宣言に使用される 従来の 4D シンタックス を、クラス関数の引数宣言に使うこともできます。 両方のシンタックスは併用することができます。 たとえば:
Function add($x : Integer) var $2; $value : Integer var $0 : Text $value:=$x+$2 $0:=String($value)
#### 例題
```4d
// クラス: Rectangle
Class Constructor($width : Integer; $height : Integer)
This.name:="Rectangle"
This.height:=$height
This.width:=$width
// 関数定義
Function getArea()->$result : Integer
$result:=(This.height)*(This.width)
// プロジェクトメソッドにて
var $rect : cs.Rectangle
var $area : Real
$rect:=cs.Rectangle.new(50;100)
$area:=$rect.getArea() //5000
Class Constructor
シンタックス
// クラス: MyClass
Class Constructor({$parameterName : type; ...})
// コード
クラスコンストラクター関数を使って、ユーザークラスを定義することができます。このコンストラクターは 引数 を受け取ることができます。
In that case, when you call the new()
function, the class constructor is called with the parameters optionally passed to the new()
function.
For a class constructor function, the Current method name
command returns: "<ClassName>:constructor", for example "MyClass:constructor".
Example:
// Class: MyClass
// Class constructor of MyClass
Class Constructor ($name : Text)
This.name:=$name
// In a project method
// You can instantiate an object
var $o : cs.MyClass
$o:=cs.MyClass.new("HelloWorld")
// $o = {"name":"HelloWorld"}
Class extends <ClassName>
Syntax
// Class: ChildClass
Class extends <ParentClass>
The Class extends
keyword is used in class declaration to create a user class which is a child of another user class. この子クラスは、親クラスのすべての機能を継承します。
クラス継承は次のルールに沿っている必要があります:
- ユーザークラスはビルトインクラスを継承できません (例外は 4D.Object で、すべてのユーザークラスにデフォルトで継承されます)
- ユーザークラスは、別のプロジェクトやコンポーネントのユーザークラスを継承できません。
- ユーザークラスは、自身を継承することはできません。
- 間接的にも、自身を継承することはできません (例: "a" extends "b" かつ "b" extends "a")。
コードエディターやインタープリターは、これらのルールが破られていても検知することはできません。コンパイラーおよび "シンタックスチェック" のみがエラーを生成します。
派生クラスは、Super
コマンドを使って親クラスのコンストラクターを呼び出すことができます。.
例題
Polygon
クラスを継承した Square
クラスを作成します。
// クラス: Square
// パス: Classes/Square.4dm
Class extends Polygon
Class constructor ($side : Integer)
// 親クラスのコンストラクターを呼び出します
// 長方形の高さ・幅パラメーターに正方形の一辺の長さを引数として渡します
Super($side;$side)
// 派生クラスにおいては、'This' を使用するより先に
// Super を呼び出しておく必要があります
This.name:="Square"
Function getArea()
C_LONGINT($0)
$0:=This.height*This.width
Super
Super {( param{;...;paramN} )} {-> Object}
引数 | 型 | 説明 | |
---|---|---|---|
param | mixed | -> | 親コンストラクターに受け渡す引数 |
戻り値 | object | <- | 親オブジェクト |
Super
キーワードによってスーパークラス (親クラス) を呼び出すことができます。
Super
は次の2つの目的のために使います:
- コンストラクターコード 内において、
Super
はスーパークラスのコンストラクターを呼び出すコマンドです。 コンストラクター内で使用する際には、Super
コマンドは単独で使用され、またThis
キーワードよりも先に使用される必要があります。継承ツリーにおいて、すべてのクラスコンストラクターが正しく呼び出されていない場合には、エラー -10748 が生成されます。 呼び出しが有効であることを確認するのは、開発者の役目となります。
スーパークラスがコンストラクトされるより先に、
This
コマンドを使った場合には、エラー -10743 が生成されます。Super
を、オブジェクトのスコープ外で呼び出した場合、または、スーパークラスコンストラクターがすでに呼び出されたオブジェクトを対象に呼び出した場合には、エラー -10746 が生成されます。
// myClass コンストラクター
var $text1; $text2 : Text
Super($text1) // テキスト型引数をスーパークラスコンストラクターに渡します
This.param:=$text2 // 2番目の引数を使用します
- クラスメンバー関数 内において、
Super
はスーパークラスのプロトタイプを指し、スーパークラス階層のメンバーメソッドの呼び出しを可能にします。
Super.doSomething(42) // スーパークラスにて宣言されている
// "doSomething" メンバーメソッドを呼び出します
例題 1
クラスコンストレクター内で Super
を使う例です。 Rectangle
と Square
クラス の共通要素がコンストラクター内で重複しないよう、このコマンドを呼び出します。
// クラス: Rectangle
Class constructor($width : Integer; $height : Integer)
This.name:="Rectangle"
This.height:=$height
This.width:=$width
Function sayName()
ALERT("Hi, I am a "+This.name+".")
// 関数定義
Function getArea()
var $0 : Integer
$0:=(This.height)*(This.width)
// クラス: Square
Class extends Rectangle
Class constructor ($side : Integer)
// 親クラスのコンストラクターを呼び出します
// 長方形の高さ・幅パラメーターに正方形の一辺の長さを引数として渡します
Super($side;$side)
// 派生クラスにおいては、'This' を使用するより先に
// Super を呼び出しておく必要があります
This.name:="Square"
Function getArea()
C_LONGINT($0)
$0:=This.height*This.width
例題 2
クラスメンバーメソッド内で Super
を使う例です。 メンバーメソッドを持つ Rectangle
クラスを作成します:
// クラス: Rectangle
Function nbSides()
var $0 : Text
$0:="I have 4 sides"
Square
クラスには、スーパークラスメソッドを呼び出すメンバーメソッドを定義します:
// クラス: Square
Class extends Rectangle
Function description()
var $0 : Text
$0:=Super.nbSides()+" which are all equal"
すると、プロジェクトメソッド内には次のように書けます:
var $square : Object
var $message : Text
$square:=cs.Square.new()
$message:=$square.description() // "I have 4 sides which are all equal"
This
This -> Object
引数 | 型 | 説明 | |
---|---|---|---|
戻り値 | object | <- | カレントオブジェクト |
This
キーワードは、現在処理中のオブジェクトへの参照を返します。 This
は、4Dにおいて 様々なコンテキスト で使用することができます。
This
の値は、呼ばれ方によって決まります。 This
の値は実行時に代入により設定することはできません。また、呼び出されるたびに違う値となりえます。
オブジェクトのメンバーメソッドとしてフォーミュラが呼び出された場合、This
はメソッドの呼び出し元であるオブジェクトを指します。 For example:
$o:=New object("prop";42;"f";Formula(This.prop))
$val:=$o.f() //42
When a class constructor function is used (with the new()
function), its This
is bound to the new object being constructed.
//Class: ob
Class Constructor
// Create properties on This as
// desired by assigning to them
This.a:=42
// in a 4D method
$o:=cs.ob.new()
$val:=$o.a //42
When calling the superclass constructor in a constructor using the Super keyword, keep in mind that
This
must not be called before the superclass constructor, otherwise an error is generated. こちらの 例題 を参照ください。
基本的に、This
はメソッドの呼び出し元のオブジェクトを指します。
// クラス: ob
Function f()
$0:=This.a+This.b
この場合、プロジェクトメソッドには次のように書けます:
$o:=cs.ob.new()
$o.a:=5
$o.b:=3
$val:=$o.f() //8
この例では、変数 $o に代入されたオブジェクトは f プロパティを持たないため、これをクラスより継承します。 f は $o のメソッドとして呼び出されるため、メソッド内の This
は $o を指します。
クラスコマンド
4D ランゲージには、クラス機能を扱う複数のコマンドがあります。
OB Class
OB Class ( object ) -> Object | Null
OB Class
は引数として渡したオブジェクトのクラスを返します。
OB Instance of
OB Instance of ( object ; class ) -> Boolean
object
が class
、またはその子クラスに属していれば、OB Instance of
は true
を返します。それ以外の場合は false
を返します。