オブジェクト指向のツボ 〜Vol7. メンバ関数のオーバーライド〜

基本クラスに実装されているメンバ関数を派生クラス独自の仕様に書き換えたいときに利用する手段がオーバーライドです。この手法はクラス継承を行ったときにやむを得ず利用する手段でもあります。

オーバーライドのやり方

派生クラスで関数を上書きする、これだけです。「Vol4.継承とアクセシビリティ」に出てきたサンプルコードに少し手を加えてみましょう。

CCarのメンバ変数をProtectedとして定義しているところに注目してください。こうすることで、派生クラスから基本クラスCCarの各メンバ変数(name、door、tire、displacement)にアクセスできるようにしています。この場合は、もちろんPublicにしても良いのですが、なるべく隠ぺい化を考慮するということで、Protectedにしています。

今回はミニバンに関するクラスCMinivanを定義します。ミニバンといっても大きさはピンキリ、乗車定員もまちまちです。ということで、CMinivanクラスには、CCarクラスでは扱っていない「乗車定員」という要素を含ませてみましょう。CCarクラスが提供しているメンバ関数Showは、乗車定員の表示ができないので、CMinivanクラスでオーバーライドを行い、メンバ関数を書き換えます。

#N88BASIC


'---------------------
' CCar クラスを定義
'---------------------

Class CCar
Protected
    name[100] As Byte    '車名
    door As Long         'ドアの枚数
    tire As Long         'タイヤの個数
    displacement As Long '排気量

Public
    'コンストラクタ
    Sub CCar(pszName As *Byte,
        NumOfDoor As Long,
        NumOfTire As Long,
        NumOfDisplacement As Long
        )

        'メンバ変数の内容を初期化
        lstrcpy(name, pszName)
        door = NumOfDoor
        tire = NumOfTire
        displacement = NumOfDisplacement

        Print "CCarのコンストラクタが呼び出されました。("+MakeStr(name)+")"
    End Sub

    'デストラクタ
    Sub ~CCar()
        Print "CCarのデストラクタが呼び出されました。("+MakeStr(name)+")"
    End Sub

    'メンバの情報を画面に表示
    Sub Show()
        Print ""
        Print "車名:";MakeStr(name)
        Print "ドアの数:";door;"枚"
        Print "タイヤの数:";tire;"個"
        Print "排気量:";displacement;"cc"
        Print ""
    End Sub
End Class

Class CMinivan
    Inherits CCar

    seats As Long    '乗車定員

Public
    'コンストラクタ
    Sub CMinivan(pszName As *Byte,NumOfDisplacement As Long, NumOfSeats As Long)
        '基本クラスのコンストラクタを呼び出す
        CCar(pszName,4,4,NumOfDisplacement)

        seats=NumOfSeats

        Print "CSedanのコンストラクタが呼び出されました。"
    End Sub

    'デストラクタ
    Sub ~CMinivan()
        Print "CSedanのデストラクタが呼び出されました。"
    End Sub

    'オーバーライド(Show関数を書き換える)
    Sub Show()
        Print ""
        Print "車名:";MakeStr(name)
        Print "ドアの数:";door;"枚"
        Print "タイヤの数:";tire;"個"
        Print "排気量:";displacement;"cc"
        Print "乗車定員:";seats;"人"
        Print ""
    End Sub
End Class

Dim objOdyssey As CMinivan("オデッセイ",2400,7)
Dim objAlphard As CMinivan("アルファード",3000,8)

objOdyssey.Show()
objAlphard.Show()

↑実行結果

隠ぺい化を考えると…

クラス隠ぺい化を考慮すると、メンバ関数のオーバーライドはあまり良いことではありません。なぜかというと、本来なら提供を受けるはずの基本クラスの機能を書き換えてしまう行為がオーバーライドそのものだからです。

オーバーライドを多用しているコードで、基本クラスを再設計するとき、派生クラスにも手を加えなければいけなくなります。こうなってくると、クラス化によるメリットが半減してしまいますね。オーバーライドを利用することは絶対的に悪いことではありませんが、できる限り、これを多用することは避けたほうが良さそうです…。



講座インデックスへ戻る ©2005 Discoversoft