1.はじめに
紹介する自作クラスの構成と概略について、おさらいしておきましょう。
このプログラムを構成する要素として、スイッチの解釈、スイッチ解釈時のエラー処理、行番号付加の3つの要素があります。
アプリ本体であるLineNumbererクラス、スイッチ解釈担当のCommandLineSwitchクラス、エラー処理担当のConsoleErrorクラス、
この行番号付加プログラムに固有ではなくCUIプログラムで共通に使う処理部分の雛型のConsoleApplicationクラスです。
今回は、ConsoleApplicationクラスの説明をします。
2.ConsoleApplicationクラス
2.1.概要
このクラスの役割は、一般的なCUIプログラムの雛型を提供することです。
このクラスが提供する機能は、以下の通りです。
| ReadLinesメソッド | 標準入力からの入力データをすべてArrayListに蓄える。
ArrayListは配列のような感じで使用できるサイズが自動調整されるコレクションクラス。 |
| WriteLinesメソッド | 蓄えておいたすべてのデータを標準出力に出力する。 |
| Linesプロパティ | 入力データは行単位でこのプロパティから参照/変更できる。 |
| AnalyzeArgumentメソッド | コマンドライン引数を解釈する抽象メソッド。
CUIプログラムがコマンドライン引数を解釈するということは各アプリで共通しているが、実際の処理はまったく異なるので、
雛形としては、このメソッドを提供することを宣言する。このメソッドの中身(実装)はこのクラスを継承したクラスが行う。 |
| ShowUsageメソッド | このコマンド(アプリ)の使用方法を標準出力に表示するメソッド。 |
2.2.ソースコードと解説
1:Imports System
2:Imports System.IO
3:Imports System.Collections
4:
5:
6:Public MustInherit Class ConsoleApplication
- [ 新キーワード : MustInherit ]
- MustInheritキーワードは、このクラスが「Must + Inherit = 継承しなければならない」クラスであることを示し、
抽象クラスを定義するときに利用します。
7: Private mLines As ArrayList = New ArrayList()
- [ クラス : ArrayList ]
- ArrayListクラスはSystem.Collections 名前空間に所属するコレクションクラスです。
コレクションクラスは旧VBのCollection、Dictionaryオブジェクトなどのような機能を持ったクラスのことをいい、
Addメソッドでデータを追加し、Removeメソッドでデータを削除できるので、動的な配列のような感覚で扱えます。
ここでは、ArrayList型の変数mLinesを宣言し、「New ArrayList()」の部分でArrayListのインスタンスを生成しています。
8:
9:
10: Public ReadOnly Property Lines() As ArrayList
11: Get
12: Return mLines
13: End Get
14: End Property
- [ プロパティの定義方法 ]
- .NETでのプロパティの定義の基本形は以下のようなイメージになります。
Public Property プロパティ名() As 型
Get
Return 内部用変数
End Get
Set(ByVal value As 型)
内部用変数 = value
End Set
End Property
- オブジェクト.プロパティ = プロパティに設定する値 ( 例: Text1.Text = "テキスト" )
- プロパティから取得した値を設定する変数 = オブジェクト.プロパティ ( 例: stringValue = Text1.Text )
1.の場合の処理を定義するのが、Set 〜 End Setの部分で、2.の場合の処理を定義するのが、Get 〜 End Getの部分です。
プログラムの10〜14行のプロパティの定義では、読み取り専用のプロパティ(Get〜End Getの処理しか行わないプロパティ)にするために、
ReadOnlyキーワードを使用しています。このReadOnlyプロパティはPublicとPropertyの間に指定します。
また、Returnキーワードも新キーワードです。これは戻り値を戻すときのキーワードです。
15:
16:
17: Public Sub ReadLines()
18: Dim line As String
19:
20: Do
21: line = Console.ReadLine()
22: If Not line Is Nothing Then
23: mLines.Add(line)
24: Else
25: Exit Do
26: End If
27: Loop
28: End Sub
- [ クラス : Console ]
- ReadLinesメソッドは、20〜27行目のDo 〜 Loop処理で標準入力からの入力をすべてArrayListに登録しています。
標準入力から1行入力を受けるのには、System.ConsoleクラスのReadLineメソッドを利用します。
このメソッドは、1行入力して最後にEnterキーを押した時点で、1行分のデータを返します(改行はそのデータには含まれません)。
返された1行分のデータは、23行目でArrayListのAddメソッドでmLinesに追加します。
ループ内で標準入力を受け続けますが、入力が終了したら(キーボード操作ならCtrl+Z、ファイルならファイルの終端(EOF))、
ReadLineメソッドはNothingを返しますので、変数lineがNothingかどうかを調べることで、
入力終了を判定します。
29:
30:
31: Public Sub WriteLines()
32: Dim line As String
33:
34: For Each line in mLines
35: Console.WriteLine(line)
36: Next
37: End Sub
- [ クラス : Console ][ 列挙 : For Each 〜 Next ]
- WriteLinesメソッドは、34〜36行目のFor Each 〜 Next処理でmLinesに蓄えた入力データをすべて標準出力に出力します。
変数mLinesはArrayListクラスなので、For Each文により中身を順次取り出すことができます。
標準出力への書き出しは、ConsoleクラスのWriteLineメソッドを使用します。データ+改行コードが出力されます。
38:
39:
40:
41:
42: MustOverride Public Function AnalyzeArgument(ByVal CmdArgs() As String) As Boolean
43:
44:
45: Public Sub ShowUsage()
46: ShowUsage(Console.Out)
47: End Sub
48:
49:
50:
51: MustOverride Public Sub ShowUsage(ByVal out As TextWriter)
52:End Class
- [ 新キーワード : MustOverride ]
- MustOverrideはVB.NETからの新キーワードで42行目と51行目で使用しています。
このメソッドが「Must+Override = オーバーライドしなければらない」な抽象メソッドであることを示します。
このメソッドには中身は書きません(End Function等も書かない)。このクラスを継承したクラスの方で、
メソッドをオーバーライドして中身を実装しなければなりません。
AnalyzeArgumentはコマンドライン引数を解釈するメソッドですが、コマンドライン引数の仕様は各コマンドごとに異なるため、
共通クラスでは実装できません。実際にアプリを作成するときに実装したいので、未定義のメソッドとしています。
ShowUsageも使用方法のメッセージ、表示の仕方は、各コマンド依存のためここでは未定義にしています。
- [ 新キーワード : Overloads ]
- Overloadsという新キーワードがあります。コード中でそんなキーワード出てこないじゃないか!!と思われるかもしれませんが、
省略しているだけだったりします。45行目と51行目をご覧下さい。両方ともShowUsageで同じ名前のメソッドです。しかし、引数の指定が異なります。
これをオーバーロードといいます。
同じ名前のメソッドで引数の型、数、順番のいずれかの異なるものを多重に定義することです。同クラス内でオーバーロードさせる場合は、特にOverloadsキーワードを指定する必要はありません。
しかし、基本クラスでメソッドAを定義し、それを継承したクラスでメソッドAの別バージョンをオーバーロードで定義する場合はOverloadsキーワードの指定が必須です。
ShowUsageメソッドを2つ用意しているのは、以下のような理由によります。
- 基本的には標準出力に使用方法を出力する
- ただし、場合によって、標準エラー出力に出力したい
3.まとめ
今回は、ConsoleApplicationクラスのメソッド、プロパティの概要を紹介し、ソースは順を追って目新しいところを説明しました。
|