よろずやネット

最近はLibreofficeにハマっています。

クラスのメソッドの上書き(オーバーライド)

Visual Basdicのプログラム作成で、いずれ遭遇する言葉に「オーバーライド」があります。
Override(覆す)という言葉から「上書き」という意味はなんとなく想像できますが、ここでオーバーライドの意味を考えてみましょう。

仮に「0312345678」という東京の電話番号があるとします。
数字の羅列だけではわかりにくいので電話番号を扱うクラスを作成し、「03-1234-5678」とヒトの目に見やすくするメソッドを追加するとしましょう。

Public Class TelNo     ' クラスの名前はTelNoです。
    Public Bangou As String ' 生の番号を代入する変数

    Public Function Tokyo As String
        Return Bangou.Substring(0,2) & "-" & Bangou.Substring(2,4) & "-" & Bangou.Substring(6,4)
    End Function
End Class

備考:
SubstringはクラスStringのメソッドで、文字列の特定の位置から文字を抜き出します。
Substring(開始位置,文字の長さ)というように指定します。
開始位置は1文字目は、0と指定します。
---
クラスTelNoを使ってみましょう。

Dim a As New TelNo
a.Bangou="0301234567"

Dim b as String = a.Tokyo

とすると、bには、文字列「03-0123-4567」が代入されます。

その後電話番号が一桁増えて、クラスTelNoを引き継いだTelNo2というクラスを作成したとします。
TelNo2でもTelNoのTokyoという「数字の羅列をヒトの目に見やすくする」メソッドが必要になりました。
ここで、クラスTelNoのメソッドTokyoのオーバーライド(上書き)です。

Public Class TelNo2
    Inherits TelNo

    Public Function Tokyo As String
        ' 文末のSubstringがSubstring(6,4)からSubstring(6,5)に変更
        Return Bangou.Substring(0,2) & "-" & Bangou.Substring(2,4) & "-" & Bangou.Substring(6,5)
    End Function
End Class


これで良さそうなのですが、Visual Basicの場合、元のクラスのメソッドはそのままでは、引き継いだクラスで上書き定義できません。
元のクラスのメソッドには、Overridable (引き継いだクラスが上書きをしてもいいですよ) を、
引き継いだクラスのメソッドには、Overrides (元のクラスの持ち物を上書きしますよ) というおまじないをつけなければなりません。


だから元のクラスは、
Public Class TelNo     ' クラスの名前はTelNoです。
    Public Bangou As String ' 生の番号を代入する変数

    Public Overridable Function Tokyo As String ' Overridableを挿入
        Return Bangou.Substring(0,2) & "-" & Bangou.Substring(2,4) & "-" & Bangou.Substring(6,4)
    End Function
End Class

引き継いだクラスでは、
Public Class TelNo2 ' 一桁増えた11桁の電話番号を扱うクラス
    Inherits TelNo

    Public Overrides Function Tokyo As String ' Overridesを挿入
        Return Bangou.Substring(0,2) & "-" & Bangou.Substring(2,4) & "-" & Bangou.Substring(6,5)
    End Function
End Class

となります。

クラスTelNo2を使ってみましょう。

Dim a As New TelNo2
a.Bangou="03012345678" ' 11桁

Dim b as String = a.Tokyo

とすると、bには、文字列「03-0123-45678」が代入されます。

-----

では、元のクラスTelNoに11桁を入れてみたらどうなるか考えてみましょう。

Dim a As New TelNo
a.Bangou="03012345678"    ' 11桁
Dim b as String = a.Tokyo

メソッドで定義してる通り、bには「03-0123-4567」(10桁)が返されます。

-----
次の場合はどうでしょう?

Dim a As New TelNo
Dim a2 As New TelNo2

a2.Bangou="03012345678" ' 11桁
a=a2          ' 10桁しか扱わないaに11桁のa2を代入

Dim b as String = a.Tokyo

この場合、bには、元のクラスのメソッドの戻り値ではなく、引き継がれたクラスのメソッドの戻り値、文字列「03-0123-45678」が代入されます。

***** 重要 *****
元のクラスの参照型を使って変数を定義しても、オーバーライドされたメソッド実行時には引き継がれたクラスのメソッドの動作をします。
******************


-------------------------------------------------------
ここでは、私自身の理解していることを再確認のために書いています。
間違いはドンドンご指摘下さい。
-------------------------------------------------------