オブジェクト指向のツボ 〜Vol4. 継承とアクセシビリティ〜

「クラスとは、構造体のメンバに関数機能が加わったようなもの」

オブジェクト指向を学習していると、このような例えをよく耳にします。この表現は間違っているとはいえませんが、オブジェクト指向を語る上でのクラス解説としては核心を削いでいます。そんなことで、今回は、構造体のメンバ変数に関数機能をつける以外に、クラスにはどのような機能が備わっているのかを解説していきます。

継承について

継承とは、あるクラスの構造を引き継ぎながら、新しいクラスを定義することを言います。例えば、「自動車」というオブジェクト(基本クラス)と「セダン」「クーペ」「ミニバン」というオブジェクト(派生クラス)には継承の関係を持たせることができます。ここで、基本クラスとは継承元となるクラスを、派生クラスとは、基本クラスを元にして新しく作られたクラスだと捉えておいてください。

継承を行うには、Class 〜 End Classステートメント内の先頭行に、"Inherits 基本クラス" を記述します。

#N88BASIC


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

Class CCar
    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


'------------------------------------------
' CCarを基本クラスにした派生クラスを定義
'------------------------------------------

'セダン
Class CSedan
    Inherits CCar
Public

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

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

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

'クーペ
Class CCoupe
    Inherits CCar
Public

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

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

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


Sub MainProc()
    'オブジェクトを生成
    Dim obj_Celsior As CSedan("TOYOTA セルシオ",4300)
    Dim obj_FairladyZ As CCoupe("日産 フェアレディZ",3500)

    obj_Celsior.Show()
    obj_FairladyZ.Show()
End Sub


Print "今からMainProc関数を呼び出します。"
MainProc()
Print "MainProc関数が終わりました。"

アクセシビリティについて

先ほどのサンプルでは、CCarのメンバ変数はすべてPrivate、その他の各関数はすべてPublicに設定されていました。では、このPrivateやPublic、一体どのような意味を持つのでしょうか。

継承に欠かせない機能が、アクセシビリティです。アクセシビリティとは、外部からクラスのメンバにアクセスできるかどうか、または派生クラスから基本クラスのメンバにアクセスできるかどうかを設定します。

サンプルコードを改良して、サンルーフ/オープンカー設定に対応しよう

せっかくアクセシビリティについて触れたので、先ほどのサンプルを少しいじって、サンルーフ(セダンのみ)またはオープンカー(クーペのみ)を指定できるようにしてみましょう。

CCarのメンバに、Protected指定でdwCarTypeという変数を追加します。次に、派生クラスCSedan及びCCoupeのメンバ関数にそれぞれSetSunroof、SetOpenCarを追加し、dwCarTypeの値を設定できるよう、仕掛けを施します。

#N88BASIC


Const CARTYPE_NORMAL  = 0
Const CARTYPE_OPEN    = 1
Const CARTYPE_SUNROOF = 2


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

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

Protected
    dwCarType As DWord

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"
        If dwCarType=CARTYPE_OPEN Then
            Print "オープンカー"
        ElseIf dwCarType=CARTYPE_SUNROOF Then
            Print "サンルーフ付き"
        End If
        Print ""
    End Sub
End Class


'------------------------------------------
' CCarを基本クラスにした派生クラスを定義
'------------------------------------------

'セダン
Class CSedan
    Inherits CCar
Public

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

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

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

    'サンルーフを付ける
    Sub SetSunroof()
        dwCarType=CARTYPE_SUNROOF
    End Sub
End Class

'クーペ
Class CCoupe
    Inherits CCar
Public

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

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

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

    'オープンカーに設定
    Sub SetOpenCar()
        dwCarType=CARTYPE_OPEN
    End Sub
End Class


Sub MainProc()
    'オブジェクトを生成
    Dim obj_Celsior As CSedan("TOYOTA セルシオ",4300)
    Dim obj_FairladyZ As CCoupe("日産 フェアレディZ",3500)

    obj_Celsior.SetSunroof()
    obj_Celsior.Show()

    obj_FairladyZ.SetOpenCar()
    obj_FairladyZ.Show()
End Sub


Print "今からMainProc関数を呼び出します。"
MainProc()
Print "MainProc関数が終わりました。"


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