例外クラス

 前節で見たように、.NET Frameworkで用意されているメソッドで発生する可能性があるものは、MSDNライブラリーに説明が載せられているので、その例外クラス名を使用して例外処理を記述できます。例外処理はそれ以外にも、自分で例外クラスを作って、発生(スロー)させることもできます。

 例外クラスを作成するには次のように記述します。

例外クラス定義の書式
Class 例外クラス名
 Inherits Exception
 …
End Class

 自分で作った例外クラスは自分でスローしなくてはなりません。例外をスローするには次のように記述します。

例外クラススローの書式
Throw 例外オブジェクト

 ここで、先回作成したBusクラスを修正しましょう。今までは、乗車や降車をするときに走っていないかどうかなどを調べ、異常がある場合はその旨のメッセージを返すように作ってきました。それを例外処理に書き換えましょう。

○ プロジェクト

 プロジェクトを作成して確認してみましょう。

プロジェクトの種類 コンソール アプリケーション
プロジェクト名 ThrowTest

サンプルダウンロード

○ 作成の準備

 「InheritanceTest」プロジェクトを修正して作成しましょう。InheritanceTestフォルダーをコピーして、作成するプロジェクト名にフォルダー名を変更してください。

○ プログラム

 例外を表すクラスを作成しましょう。Exceptionクラスを継承した次のようなクラスを作成してください。

WarningException.vb

  1. Public Class WarningException
  2.  Inherits Exception
  3.  Public Sub New(errormessage As String)
  4.   MyBase.New(errormessage)
  5.  End Sub
  6. End Class

○ 解説

 2行目でスーパークラスにExceptionクラスを指定しています。それにより今回作成したWarningExceptionクラスはスローしてキャッチすることができるようになります。例外を表すクラスは多くの場合~Exceptionのように名前を付けます。

 4~6行目ではコンストラクタを定義しています。このコンストラクタはインスタンス生成時にスーパークラスであるExceptionクラスのコンストラクタを呼び出しています。引数として受け取ったエラーメッセージをさらに引数として渡しています。これによりMessageプロパティで、引数で指定したエラーメッセージが参照できるようになります。

○ プログラム

 次にBusクラスを変更しましょう。次のように修正してください。

Bus.vb

  1. Public Class Bus
  2.  Inherits Car
  3.  'プロパティ==========
  4.  Public Property SalesAmount As Integer     '運賃
  5.  Public Property PassengerNumber As Integer     '乗客人数
  6.  'コンストラクタ==========
  7.  Public Sub New()
  8.   Me.New(100)
  9.  End Sub
  10.  Public Sub New(gas As Double)
  11.   MyBase.New(gas)
  12.   Me.SalesAmount = 0
  13.   Me.PassengerNumber = 0
  14.  End Sub
  15.  'メソッド==========
  16.  '乗車させるメソッドAs String
  17.  Public Sub RideToBus(fare As Integer)
  18.   '走行中かどうか
  19.   If Me.Speed <> 0 Then
  20.    Throw New WarningException("停車してください。")
  21.   End If
  22.   '満席かどうか
  23.   If Me.PassengerNumber >= 50 Then
  24.    Throw New WarningException("満席のため、乗車できません。")
  25.   End If
  26.   '料金と、乗車人数を加算
  27.   Me.SalesAmount += fare
  28.   Me.PassengerNumber += 1
  29.  End Sub
  30.  '降車させるメソッド
  31.  Public Sub GetOffBus()
  32.   '走行中かどうか
  33.   If Me.Speed <> 0 Then
  34.    Throw New WarningException("停車してください。")
  35.   End If
  36.   '乗客がいるかどうか
  37.   If Me.PassengerNumber = 0 Then
  38.    Throw New WarningException("乗客はいません。")
  39.   End If
  40.   '乗車人数を減算
  41.   Me.PassengerNumber -= 1
  42.  End Sub
  43. End Class

○ 解説

 20、35行目では、処理の中でエラーが発生した場合は文字列を返す仕組みから例外をスローする仕組みに変更するため、戻すデータがなくなりました。そのため、プロシージャの種類をFunctionからSubに変更しています。

 23、27、38、42行目では、エラーが発生した場合にその時のエラーメッセージをReturn文で返していましたが、Throw文を使って例外をスローさせるように変更しました。

○ プログラム

 次にMainソッドを変更しましょう。次のように修正してください。

Module1.vb

  1. Module Module1
  2.  '車の状態を表示するメソッド
  3.  Sub ShowData(c As Bus)
  4.   Console.WriteLine("スピード:{0}km", c.Speed)
  5.   Console.WriteLine("ガソリン:{0}L", c.Gas)
  6.   Console.WriteLine("売上金額:{0}円", c.SalesAmount)
  7.   Console.WriteLine("乗車人数:{0}人", c.PassengerNumber)
  8.  End Sub
  9.  Sub Main()
  10.   'インスタンスを生成する
  11.   Dim obj As New Bus(150)
  12.   '現在の状態を表示する
  13.   ShowData(obj)
  14.   While True
  15.    Try
  16.     '操作を入力
  17.     Console.Write("1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:")
  18.     Dim inputdata As String = Console.ReadLine()
  19.     '操作によって分岐する
  20.     Select Case inputdata
  21.      Case "1"
  22.       '加速する
  23.       obj.SpeedUp(5)
  24.       ShowData(obj)
  25.      Case "2"
  26.       '減速する
  27.       obj.SpeedDown(5)
  28.       ShowData(obj)
  29.      Case "3"
  30.       '給油する
  31.       'obj.SetGas(35)
  32.       obj.Gas = 80
  33.       ShowData(obj)
  34.      Case "7"
  35.       '乗車する
  36.       obj.RideToBus(200)
  37.       ShowData(obj)
  38.      Case "8"
  39.       obj.GetOffBus()
  40.       ShowData(obj)
  41.      Case "9"
  42.       'プログラムを終了する
  43.       Return
  44.     End Select
  45.    Catch ex As WarningException
  46.     Console.WriteLine(ex.Message)
  47.    Catch ex As Exception
  48.     Console.WriteLine("エラーが発生しました。")
  49.     Console.WriteLine(ex.Message)
  50.    End Try
  51.   End While
  52.  End Sub
  53. End Module

○ 解説

 19~55行目では、Try~Catch文が記述されています。41、44行目で、バスオブジェクトのメソッドが呼び出されると、状態によって例外(WarningException)がスローされてきます。その場合は、50行目でキャッチされ、51行目の処理が行われます。52行目はWarningException以外がTry文の中でスローされたときにキャッチされます。

 Catch文は複数指定することができます。Try文でスローされた例外オブジェクトに応じてキャッチされます。それぞれのCatch文が上から順に評価されていきます。そのため、Exception型のCatchは最後に指定しないと警告が表示されます。上の方にExeption型の指定をすると必ずそこでキャッチされ、下に指定したCatch文は使われないからです。

前へ   次へ