オーバーライド
サブクラスはスーパークラスのメンバを継承することができますが、状況によってはスーパークラスの処理の内容を変更しなくてはならない場合があります。サブクラス側で同じメソッド名でかつ、同じシグネチャ(引数の構成)のメソッドを再び定義することができます。これをメソッドのオーバーライド(override)と呼びます。
例えば、Carクラスでは、スピードの制限がありません。基本的に無限にスピードが出るように設計されています。しかし、Busではスピードの制限を設けないと危険なので、速度の制限を設けたいと思います。
Busクラスでオーバーライド
では、Busクラスの定義を修正してみましょう。オーバーライドするためには、スーパークラス側と、サブクラス側でオーバーライドの指定をしなくてはなりません。
■ オーバーライドされる側
Public Overridable Sub SpeedUp(sp As Integer)
・・・
End Sub
■ オーバーライドする側
Public Overrides Sub SpeedUp(sp As Integer)
・・・
End Sub
○ プロジェクト
プロジェクトを作成して確認してみましょう。
プロジェクトの種類 |
コンソール アプリケーション |
プロジェクト名 |
OverrideTest |
サンプルダウンロード
○ 作成の準備
Busクラスにメソッドを追加しましょう。「InheritanceTest」をコピーしてプロジェクトを作成してください。
○ プログラム
まず、CarクラスのSpeedUpメソッドにvirtualキーワードを追加します。
Car.vb
- Public Class Car
- 'フィールド==========
- 'Public _speed As Integer 'スピード情報
- Private _speed As Integer 'スピード情報(修正)
- 'Public _gas As Double 'ガソリン情報
- Private _gas As Double 'ガソリン情報(修正)
- 'メソッド==========
- '加速させるメソッド
- Public Overridable Sub SpeedUp(sp As Integer)
- 'ガソリンを減らす
- Me._gas -= sp / 10.0
- If Me._gas < 0 Then 'ガソリンがマイナスになる場合
- 'ガソリンを0に補正し、スピードを増やさない
- Me._gas = 0
- Else
- 'スピードを増やす
- Me._speed += sp
- End If
- End Sub
○ 解説
42行目のメソッドの定義でOverridableキーワードを追加しました。これにより、Carクラスを継承したクラスでSpeedUpメソッドをオーバーライドできるようになります。
○ プログラム
次に、BusクラスにSpeedUpメソッドを追加します。
Bus.vb
- Public Class Bus
- Inherits Car
- 'プロパティ==========
- Public Property SalesAmount As Integer '運賃
- Public Property PassengerNumber As Integer '乗客人数
- 'コンストラクタ==========
- Public Sub New()
- Me.New(100)
- End Sub
- Public Sub New(gas As Double)
- MyBase.New(gas)
- Me.SalesAmount = 0
- Me.PassengerNumber = 0
- End Sub
- 'メソッド==========
- '乗車させるメソッド
- Public Function RideToBus(fare As Integer) As String
- '走行中かどうか
- If Me.Speed <> 0 Then
- Return "停車してください。"
- End If
- '満席かどうか
- If Me.PassengerNumber >= 50 Then
- Return "満席のため、乗車できません。"
- End If
- '料金と、乗車人数を加算
- Me.SalesAmount += fare
- Me.PassengerNumber += 1
- Return Nothing
- End Function
- '降車させるメソッド
- Public Function GetOffBus() As String
- '走行中かどうか
- If Me.Speed <> 0 Then
- Return "停車してください。"
- End If
- '乗客がいるかどうか
- If Me.PassengerNumber = 0 Then
- Return "乗客はいません。"
- End If
- '乗車人数を減算
- Me.PassengerNumber -= 1
- Return Nothing
- End Function
- '加速させるメソッド(オーバーライド)
- Public Overrides Sub SpeedUp(sp As Integer)
- If (Me.Speed + sp) <= 60 Then
- MyBase.SpeedUp(sp)
- End If
- End Sub
- End Class
○ クラス図
○ 解説
51~55行目でOverridesキーワードを指定してSpeedUpメソッドを再定義しています。このメソッドは加速後のスピードが60km/h以下ならスーパークラスであるCarクラスのSpeedUpメソッドを呼び出して加速しています。MyBaseキーワードはスーパークラスを指すので、MyBase.XXと指定することでスーパークラスのメンバを指定することができます。
プログラムの修正はこれで終了です。Busクラスを利用するプログラムは修正をしませんが、60km/hまでしかスピードが出ないようになっています。これは実際のバスの運転手がバスのアクセルを踏むと自動的に60kmまでしかスピードが出なくなる状況と似ています。もしオーバーライドができないと次のようにメソッドを用意することになるかもしれません。
オーバーロードを使わないと…
上の図の例だとBusクラスを利用する側では「SpeedUp」と「SpeedUpForBus」というメソッドのどちらを呼び出すかを選択することになります。実際のバスの例だと、無限にスピードが出るアクセルと、60kmまでしかスピードが出ないアクセルが2つ並んでいる状態ということができます。バスの操作説明書には、「アクセルは2つありますが、必ず60㎞/hまでしかスピードが出ないアクセルを踏むようにしてください」とあったとしても、操作ミスで無限にスピードが出るアクセルを踏んでしまうかもしれませんし、スピード狂の運転手であれば、リミッターのかからない(無限にスピードが出る)アクセルをあえて踏むかもしれません。
オーバーライドで「SpeeUp」メソッドを再定義することにより、実際のバスでアクセルは1つあるという状態を作り出すことができます。これにより、バスを安全に運用してもらうことが可能になりますし、運転手を再教育する必要はなくなるということになります。それは、使用している部品がバージョンアップしても、使い方は変わらない(プログラムを変更しなくてもよい)ということになります。
前へ 次へ