ベースクラスで定義されたプロパティまたはメソッドは、派生クラスで使用できます。また、派生クラスで使用されるベースクラスのプロパティとメソッドの動作のモデルを変更することもできます。これは、プロパティの上書きやメソッドの上書きと呼ばれます。
派生クラスでプロパティを再定義することにより、ベースクラスのプロパティを上書きします。同様に、派生クラスでサブルーチンまたは関数を再定義することにより、メソッドを上書きします。上書きするメソッドの先頭部は、ベースクラスのメソッドの先頭部と同じでなければなりません。派生クラスのメソッドに対するパラメータは、ベースクラスのメソッドに対するパラメータと正確に一致する必要があります。
次の例では、継承によって関連する 2 つのクラス作成します。スクリプトは Fruit という名前のベースクラスを宣言し、続いて Fruit クラスから新しく Apple クラスと Banana クラスを派生させます。Apple クラスと Banana クラスは Fruit クラスのすべての変数 (weight と color) と Prepare サブルーチンを継承します。
Prepare サブルーチンはベースクラスでは意図的にブランクになっています。このサブルーチンは一般的なアクセスを提供し、Fruit サブルーチンを介して Apple または Banana の特性にアクセスできるように、派生クラスで上書きまたは拡張できます。これらの派生クラスは両方ともベースクラスの Prepare サブルーチンを上書きします。Apple クラスは Core サブルーチンで置き換え、Banana クラスは Peel サブルーチンで置き換えます。
Class Fruit
weight As Single
color As String
Sub New(w As Single, c As String)
weight! = w!
color$ = c$
End Sub
Sub Prepare
' Assume that each derived class will override
' the Prepare method.
' Print a message...
Print "The Fruit class's Prepare sub doesn't do anything."
End Sub
End Class
Class Apple As Fruit ' Derive the Apple class from the 'Fruit class.
seedCount As Integer
variety As String
Sub Core ' Add a Core sub to the Apple class.
If (weight! > 5) Then ' You can access base class members.
Print "This apple core method is for apples " & _
"of 5 lbs. or less."
Exit Sub
End If
'...
Print "The ";weight!;" lb. ";color$;" "; variety$; _
" apple is cored."
End Sub
Sub New(w As Single, c As String, v As String, _
s As Integer), Fruit (w!,c$)
Variety$ = v$ ' Initialize the variety.
SeedCount% = s% ' Initialize the number of seeds.
End Sub
Sub Prepare
Core ' To prepare an apple, you core it.
End Sub
End Class
Class Banana As Fruit
' Banana class is derived from the Fruit class.
Sub Peel ' Add a peel method to the Banana class.
'.
Print "The ";weight!;" lb. ";color$; _
" Banana is now peeled."
End Sub
Sub New(w As Single, c As String)
'...
End Sub
Sub Prepare
Peel ' To prepare a banana, you peel it.
End Sub
End Class
Sub New を派生クラス用に定義して、ベースクラスの Sub New 定義を拡張できます。派生クラス用の Sub New は、ベースクラスの Sub New をパラメータも一緒に提供する必要があります。
ベースクラスの Sub New のパラメータリストは、派生クラスの Sub New のパラメータリストのサブセットになります。モジュールレベルで宣言された定数や変数も含め、任意の式をベースクラスの Sub New に対する引数として渡すことができます。派生クラス用の Sub New の引数とベースクラス用の Sub New の引数が同じであれば、ベースクラスの Sub New の引数を省略できます。
構文は次のとおりです。
Sub New [ ( paramList ) ] [ , baseClass ( baseArgList ) ]
[ statements ]
End Sub
要素 |
説明 |
---|---|
paramList |
Sub New のパラメータ宣言のリスト (カンマ区切り)。各パラメータ宣言には、次の構文を使用します。 [ ByVal ] paramName [ ( ) | List ] [ As dataType ] ByVal は、paramName を値渡しします。paramName に代入された値は、その値へのポインタではなく、メモリ内の値のローカルコピーです。paramName() は配列変数です。List は paramName をリスト変数として識別します。それ以外の場合、paramName には LotusScript® でサポートされるその他すべての型の変数を指定できます。As dataType は変数のデータ型を指定します。 |
baseClass |
クラスの派生元のクラスの識別子です。baseClass は派生クラスの Class ステートメント中の baseClass と同じでなければなりません。 |
baseArgList |
ベースクラスの Sub New 用の引数のリスト (カンマ区切り)。これらの引数は、baseClass の Sub New に渡されます。ベースクラスの Sub New に対する引数が派生クラスの Sub New に対する引数と、数値やデータ型で一致しない場合、または派生クラスの Sub New に渡される引数とは異なる引数を baseClass の Sub New に渡す場合、この引数リストを指定します。 |
次の派生クラスの Sub New は、モジュールレベルで宣言された 2 つの変数をベースクラスに渡します。
Class Fruit
Public weight As Single
Public color As String
Sub New(w As Single, c As String)
weight! = w!
color$ = c$
Print "Fruit New() weight = ";w!, "color =";c$
End Sub
End Class
Class Banana As Fruit
Sub Peel
'...
End Sub
' Banana accepts only a weight. The Sub New passes both
' weight and color to the base class (Fruit).
Sub New(w As Single), Fruit (w, "Yellow")
'...
Print "Banana New() Weight = ";w!
End Sub
End Class
Dim z As New Banana (0.45) ' Create a .45 lb yellow banana.
派生クラスのオブジェクトが作成されるとき、派生クラスの Sub New への呼び出しがベースクラスの Sub New への呼び出しを生成します。そのベースクラスも派生クラスであれば、そのベースクラスへの呼び出しが生成されます。すべての呼び出しの後で最高レベルの Sub New が実行され、続いて派生チェーン内の各クラスの Sub New が次々に実行されます。作成中のオブジェクトのクラスの Sub New は最後に実行されます。
派生クラスのオブジェクトが削除されるとき、派生クラスの Sub Delete が呼び出されて実行された後にベースクラスの Sub Delete が呼び出され、最高レベルのベースクラスまで派生チェーン内の各クラスの Sub Delete が次々に呼び出されます。つまり、実行順序は Sub New の場合とは逆になります。
次の例では、Sub New と Sub Delete が呼び出される順序を示しています。
Class Fruit
Public weight As Single
Public color As String
Sub New(w As Single, c As String)
weight! = w!
color$ = c$
Print "Fruit: New"
End Sub
Sub Delete
Print "Fruit: Delete"
End Sub
End Class
Class Apple As Fruit
Public seedCount As Integer
Sub Core
' ...
End Sub
Sub New(w As Single, c As String)
Print "Apple: New"
End Sub
Sub Delete
Print "Apple: Delete"
End Sub
End Class
Dim y As New Apple(1.14, "Red")
' Executes Fruit's Sub New and then Apple's Sub New.
Delete y
' Executes Apple's Sub Delete and then Fruit's Sub Delete.
派生クラスでメソッドが上書きされていたとしても、派生クラスはベースクラスのプロパティやメソッドを呼び出すことができます。ベースクラスの上書きされたメソッドにアクセスするには、2 つのドット (ドット表記法) を使用します。2 つのドットを使用する表記法はクラスのスコープ内 (Class ステートメント内) だけで有効です。
構文は次のとおりです。
baseClassName .. propertyName (parameters)
または
baseClassName .. methodName (parameters)
例えば、処理を追加するためだけにメソッドを上書きすることもできます。その場合、ベースクラスのメソッドを呼び出し、続いて派生クラスのメソッド内で追加処理を実行します。
オブジェクト参照は、メソッドに対する引数として、またはそれを受け付けるように定義されたプロシージャに対する引数として渡すことができます。プロシージャの戻り値としてオブジェクト参照を使用することもできます。LotusScript ではオブジェクトは値渡しではなく、参照渡しされます。
オブジェクト参照をプロシージャに渡すときは、次の規則を念頭に置いてください。
次の例では、オブジェクトを引数としてとるために、モジュールレベルで PrintAccount サブルーチンを定義しています。
Class Account
Sub DepositMoney
Print "In Account's DepositMoney sub."
End Sub
End Class
Class CheckingAccount As Account
Sub DepositMoney
Print "In CheckingAccount's DepositMoney sub."
End Sub
End Class
Sub PrintAccount(AccountArg As Account)
Call AccountArg.DepositMoney
End Sub
Dim X As New Account
Call PrintAccount(X) 'Calls Account's DepositMoney method.
Dim Y As New CheckingAccount
' Calls CheckingAccount's DepositMoney sub. Y is legal as an
' argument to PrintAccount, because CheckingAccount is a
' derived class of Account.
Call PrintAccount(Y)
派生クラスオブジェクトへの参照を含む変数を、そのオブジェクトの任意のベースクラスへの参照を含むことのできる変数に割り当てられます。例えば、CheckingAccount クラスは Account クラスから派生しているため、CheckingAccount 型の変数の値を Account 型の変数に代入できます。
ベースクラスの変数内の参照を、派生クラスのオブジェクトを参照する変数に割り当てることはできません。例えば、Account クラスの変数の中の参照を CheckingAccount クラスの変数に代入することはできません。このような代入ができてしまうと、ユーザーは参照されるオブジェクトに CheckingAccount のメソッドを使用できると期待するかもしれません。しかし、オブジェクトは Account クラスのものかもしれないため、メソッドは存在しないことがあります。
Class Account
'...
End Class
Class CheckingAccount As Account
'...
End Class
Dim X As New Account
Dim Y As New Account
Dim Z As New CheckingAccount
' Legal assignment of the contents of a base-class variable ' to a base-class variable
Set X = Y
' Legal assignment of the contents of a derived-class variable ' to a base-class variable
Set X = Z
' Cannot assign base-class variable to derived-class variable.
Set Z = X ' Illegal
最後のステートメントは、正しくありません。なぜなら、Set X = Z ステートメントの後で、変数 X が派生クラス CheckingAccount のオブジェクトを参照しています。しかし、ステートメント Set Z = X はベースクラスのオブジェクト参照変数 X の値を派生クラスのオブジェクト参照変数 Z に割り当てようとします。