KEN's .NET

[第1回] 特集!VB.NET初体験!

ホーム > KEN's .NET > [第1回] 特集!VB.NET初体験!

ども。VS.NET Beta2を手に入れました。ということでVB.NETなどの.NETの情報を提供しようと思います。

目次

  1. はじめに
  2. VS.NETはWindows 9x系にはインストールできない!?
  3. 第一印象 Java + MFCのような感じ
  4. 名前はフルスペルで
  5. プロパティ、メソッド、イベントが超たくさん!

1.はじめに


2.VS.NETはWindows 9x系にはインストールできない!?

自宅マシンのWindowsMeにインストールしようとしたら、 このシステム構成ではインストールできない旨のメッセージがでてインストールできませんでした。 WindowsNT4.0、Windows2000、WindowsXPにしかインストールできないとのこと。 Windows2000を購入して、インストールを行いました。

まずは、システムのアップデートから。 4回くらい再起動しながら、IE6のインストール。Windows2000ServicePack2へのバージョンアップが自動で行われたのち、 VS.NETのインストールがはじまり、たぶん30分ほどでインストール完了 (もっと短かったかもしれないし、もっと長かったかもしれません)。 HDDは計3GByteくらい消費するらしい。うーむ。

PentiumIII 1GHz、メモリ:384MB
起動にかかる時間はそれほどもでありません。さくさく動いています。 (現時点ではほぼ最高スペックなので、そうでないとかなり困ったことなんですが)


3.第一印象 Java + MFCのような感じ

私がぱっとVB.NETを見て思った第一印象です。VB.NETはJavaに非常に似ているなと思いました。
#後ほど、C#も少し触ってみたのですが、VB.NETと激似でした。コードの記述方法がC言語風なだけで・・・。

そしてやたらとメソッド、プロパティ、イベントが増えています。 VB6までで足りていなかったものが一通り出そろった感じ(ぱっと見)で、 できないことはなさそうです。この量と内容がちょっとVC++のMFCっぽい。
(こちらの話題は「プロパティ、メソッド、イベントが超たくさん!」で扱います)

VBでオブジェクト指向なプログラミングを行った場合、 オブジェクト指向としてのJavaの有用な機能のいくつかが足りないのを除けば、結構Javaと似ています。 が、今回その足りていないところが大幅に補強されました。(というかJavaぱくり放題な気も・・・) 主なところで従来のVBにはクラスメソッド(及び変数)、(引数付きの)コンストラクタ、(実装の)継承がありませんが、 すべて使えるようになっています。

クラスメソッド、及び、クラス変数

VBにはこれらの手段は用意されていなかったので、 あるクラスに属すべきメソッドでも標準モジュールに記述するしかありませんでした。 同様に同じクラスの各インスタンスで共通に利用する変数も標準モジュールに記述するしかありませんでした。

クラスメソッド、クラス変数としてそれぞれ標準モジュールに記述しても、 所詮はクラスメソッド、クラス変数もどきでしかないので、 これではプログラム内のどこからでもその変数、そのメソッド(というより関数)にアクセスできてしまいます。

VB.NETではよりオブジェクト指向な方向へ進化して、 プログラムのコードはすべて何らかのクラス内に記述するようになりました。 これにより必然的にすべてのメソッド、属性はクラスの中に入ることとなり、厳密なアクセス制限ができます。 クラスメソッド、クラス変数を使うときにJavaではstaticキーワードを使用しますが、 VB.NETではSharedキーワードを使用します。

コンストラクタ

従来のVBでは、インスタンスを生成してから、何らかのプロパティに初期値を与えるのに 以下のように最低限、2ステップ必要です。

(1)<従来のVB>
  Set c = New Class1
  c.Property1 = ほげほげ           

それに対して、VB.NETでは、以下のように1ステップで記述できます。(コンストラクタの中でほげほげをProperty1に設定)
(2)<VB.NET>
  c = New Class1(ほげほげ)         

このことには単に2行が1行になるということだけではなく、それとは別に大きなメリットがあります。

1. 初期値の設定

今まではインスタンスを生成する際に同時に属性に値を設定できなかったので、 クラスの作り手側の意図として、Property1に対して何らかの初期値を与えることが必須でも、 その意図を表現する手段がなく、(1)のようなコードを書かざるをえませんが、 このコードには、「Property1はClass1のインスタンスが生成されたら、すぐに設定しないといけないプロパティですよ」 という主張が見えません。単にインスタンス生成した後にProperty1に値を設定しているという事実があるだけです。 そのため、上記の「c.Property1 = ほげほげ」はインスタンス生成直後に必須の内容なのにそれを抜かしてしまい、 後でエラーになるということが考えられます。

これに対して、VB.NETでは(2)のようにインスタンス生成時に引数として初期値を渡せるので、 確実に必要な情報を最初に設定させることができます。 (引数が必要なコンストラクタのみ定義しておけば、「New Class1」のように書いてもEnterキーを押した時点で文法チェックに引っかかります)

ちなみに、従来のVBでは、あるクラスのインスタンスを生成したときに、そのクラスのInitializeイベントが呼ばれます。 クラス内部の変数を初期化したい場合、このInitializeイベントで初期化できますが、 クラスを使用する側のコードから何らかの値を指定して欲しい場合には、これでは不十分でした。 VB.NETではコンストラクタがInitializeイベントの意味合いも持っているので吸収されてなくなったようです。

2. 読取専用

上記(1)のコードで、c.Property1 = ほげほげ と設定していますが、 ただ一度だけしか設定して欲しくない場合(変更不可にしたい場合)、 c.Property1に厳密に一度だけしか代入を許可しないようなアクセス制限の方法はありませんでした。 (※ActiveXは別として、素のclsファイルのままでクラスを使う場合の話です。)

VB.NETで(引数付き)コンストラクタが導入されたことで、厳密に一度だけ値を設定できるプロパティを用意できます。 具体的には、インスタンス生成時にコンストラクタを介して一度だけProperty1の内部変数に値を設定するようにします。 また、Property1は参照しかできないようにしておきます。こうすると1度だけプロパティに値を設定でき、 それ以後は、参照しかできない状態にできます。(以下:例)

   Private mobjProperty1 As ほげほげ型  ' Property1の値を保持しておくための内部変数
 
   ' コンストラクタはNewという名前のSubプロシージャになっています。
   ' 初期値を設定できるように、引数objPropを持ったメソッドにします。
   Public Sub New(ByVal objProp As ほげほげ型)
        mobjProperty1 = objProp     ' オブジェクトの参照の代入にSetは不要になりました。
                                    ' Setを記述してもOKですが、改行後に”Set”は削除されます。
   End Sub

   ' Property1は参照しかできないようにしたいので、
   ' ReadOnlyを指定して、Get〜End Getだけを記述します。
   Public ReadOnly Property Property1() As ほげほげ型
        Get
            Property1 = mobjProperty1
        End Get
   End Property

継承

継承には以下の2種類があります。

★★インターフェースの継承

従来のVBでは、前者のインターフェースの継承しかありませんでした。 例えば、グラフィカルな外観を持つクラスのために、Drawメソッドを持ったIShapeインターフェースを用意するとします。 で、四角形、円を表すCRectangleクラス、CCircleクラスを用意する場合に、 Implementsキーワードを使って、このインターフェースを継承することにします(左図)

このようにするとIShapeを継承したCRectangle、CCircleは、 IShapeインターフェースの規格にのっとったDrawメソッドを必ず持っていることになります。 これらのクラスを使用する側のコードでは、(右図)のようにしてDrawメソッドを使用します。

(左図)

<IShapeクラス側>
   Public Sub Draw()
   End Sub

<CRectangleクラス側>
  Implements IShape

  Public Sub IShape_Draw()
      四角形を描画する内容              
  End Sub

<CCircleクラス側>
  Implements IShape

  Public Sub IShape_Draw()
       円を描画する内容
  End Sub

(右図)

   Dim objShape As IShape
   Dim objRect As CRectangle            
   Dim objCircle As CCircle

   Set objRect = New CRectangle
   Set objCircle = New CCircle

   Set objShape = objRect
   objShape.Draw

   Set objShape = CCircle
   objShape.Draw

従来のVBでは、(右図)のように、IShapeインターフェースから継承したDrawメソッドを使用するには、 一旦IShape型の変数に代入する必要がありました。これはとても面倒ですし、また、必要不可欠なコードの中に、 こういうあまり意味のないコードを含めることでコード全体が美しくなくなります。 VB.NETではIShape型の変数にいれなおさなくてもDrawメソッドが使用できるようになっています。(^^)v

VB.NETから追加されたオプションにOption Strictがあり、 これは暗黙の型変換を禁止するものですが、これをOff(デフォルト)に指定している場合に上記に書いたように、 IShape型へ明示的に変換しなくてもDrawメソッドを使えるようです。On(明示的型変換の強制をする)にした場合、 以下のように、

CType(objShape, IShape).Draw
新関数CTypeを利用して明示的にIShape型に変換する必要があります。

★★実装の継承

従来のVBにはなかった実装継承が追加されました。

オブジェクト指向の柱として、データの抽象化、多態性(ポリモーフィズム)、継承があり、 C++やJavaではもとより(実装の)継承が使用できましたが、VBでは実装継承はありませんでした。 これがないために他のオブジェクト指向言語の使用者からはVBはオブジェクト指向言語ではない と言われていました。

さて、C++では複数のクラスから継承する多重継承を行えますが、VBはJava同様、多重継承はできない仕様のようです。 実装継承は、Inheritsキーワードを用いて以下のように記述します。

   Public Class frmMain
    Inherits System.Windows.Forms.Form   
Inheritsキーワードはクラス名の記述の行のすぐ次の行に書かなければなりません。間にはコメントや空行も入れられません。


4.名前はフルスペルで

省略的命名から略さない命名へ

オブジェクト指向では名前が重要な位置を占めます。中途半端な省略はしてはならないという風潮があります。 フルスペルで書かれてあれば、各人独自の省略表記のせいで意味不明だということがなくなるからです。
#もっともネーミングセンスの無い命名をしてしまえばフルスペルでも混乱を招くでしょうけれど。

BASICは古くから続いている言語のため、関数名などに典型的な省略単語が頻繁にでてきます。 これはネーミングの観点から言ってオブジェクト指向とはなじみません。 VB6からの移行のために、今までの関数もほとんどVisualBasic用のライブラリとしてサポートされていますが、 その機能と同等のものがクラスライブラリにプロパティ、メソッド等で用意されています。.NETでプログラミングをする際に、 クラスライブラリを利用しない手はないので、新規開発の場合は、クラスライブラリの機能の方を利用した方がよいでしょう。

例えば、文字列操作関数Left、Mid、Rightは、String型のインスタンスメソッドSubstringに吸収されています。 Substringメソッドはオーバーロードにより、以下の2種類の使用方法(ヘルプより引用)をサポートしています。

Retrieves a substring from this instance. The substring starts at a specified character position.
(訳:このインスタンスから部分文字列を取得する。その部分文字列は指定した文字位置から始まる。)
  Overloads Public Function Substring(Integer) As String

Retrieves a substring from this instance.The substring starts at a specified character position and 
has a specified length.
(訳:このインスタンスから部分文字列を取得する。その部分文字列は指定した文字位置から始まり、指定した長さを持つ。)
  Overloads Public Function Substring(Integer, Integer) As String

元々、Left、Mid、Rightって3つも必要か?と言えなくもない関数群でしたが、 Substring(部分文字列)という言葉で表したこととオーバーロードの利用によりシンプルな表現になっています。
#とかなんとか言ってみるも、要はJava風のネーミングに寄っただけとも言う。

また、APIの使用時などに矩形(長方形)の座標情報を渡すときは、VCでRect構造体が使われているので(VC++でのクラスではCRect)、 VBからAPIを呼ぶ場合もRect構造体を使用していました。 このRectはRectangle(長方形)という単語を縮めてそう命名されていたわけですが、 .NETでの矩形を表す構造体はRectangleと省略なしの単語になっています。 このように省略しない一般的な英語の表記にするような方向に向かうようです。

基本的に用意されているクラスを使う場合、ほとんどはフルスペルなので、それをそのまま使用すればよいのですが、 自分でクラスを作成する場合は、プロパティ、メソッド、イベントの命名は避けられません。 センスが必要なのはもちろんですが、英語力が必須となってくるでしょう。

より難しい英語が・・・。

自分で命名するときには簡単な英語を使うように心がけることが大事ですが、 他人の命名したものは単純にその命名を理解するようにつとめるしかありません。

VB.NETでChar型というUNICODEの1文字に対応したデータ型が追加されていますが、 その中にIsPunctuation、IsSurrogateというメソッドがあります。 意味わかりますか?私にはわかりませんでした。ヘルプより最初の説明文を抜粋しますと、

IsPunctuation
  Indicates whether a Unicode character is categorized as a punctuation mark.
  (訳:punctuation markとして分類されるUNICODE文字かどうかを示す)

IsSurrogate
  Indicates whether a Unicode character is categorized as a surrogate character.
  (訳:surrogate文字として分類されるUNICODE文字かどうかを示す)

という意味です。・・・って、これでは意味不明です。 辞書を調べるとpunctuation markは句読点の意味で、「,(コンマ).(ピリオド)?(クエスチョン)-(ハイフン)など」とあります。 しかし、実際にこのメソッドを使って試してみると、どうも句読点かどうかをTrue/Falseで返すというものではないようです。 Webで調べてみると、SmallTalkに同じ名前のメソッドがあり、そちらでは、
isPunctuation 
  Returns true if self is one of '.,:;!?' 
とあり、これなら調べる文字が句読点ならTrueを返すというので妥当そうです。 .NETのIsPunctuationはどうも英数字、平仮名、漢字、スペースとそれ以外っぽい気がします。 "「"や、「"」や、「、。」などもTrueが返ってきます。まだ、実験が足りないので、なんとも言えない状況です。

では、surrogate characterはどうでしょう? surrogateを辞書で調べると、「(1)代理人 (2)遺言検認判事 (3)監督代理」とだけあります。 代理人が今回の場合の意味っぽいですが、だとして代理人文字っていったい何??? という感じで意味がさっぱりわかりません。 これも実験して・・・となるところですが、細かい話になりすぎているので、 また今後取り上げることとして、この話題はここまでとします。

要は英語力がより重要になるそうだということを言いたいわけです。

surrgate charについての事後報告
まず前提となるのがUNICODEの存在です。UNICODEには大雑把にいって、UCS2、UCS4というのがあり、それぞれ2バイトで1文字、4バイトで1文字を表現します。 で、現在は、UCS2が使用されており、UCS4は提案段階だそうです。そして、UCS2の文字コードの割り当ての中に、 特殊コード上位1バイト、文字の表現1バイト、特殊コード下位1バイト、文字の表現1バイトという形で、4バイトの文字を表現するための特殊な用途ようの 文字コードの割り当てがあるそうで、その特殊な文字をサロゲート文字というそうです。


5.プロパティ、メソッド、イベントが超たくさん

タイトルの通り、.NETでは半端じゃなくプロパティ、メソッド、イベントが増えています。 例えば、Formの場合、プロパティウィンドウに表示されている分のプロパティだけで、50個を超えています。 プロパティウィンドウにはVB.NETでは、イベントも表示項目となっており、こちらも50個以上あります。 プロパティウィンドウの様子は以下のような感じです(項目のジャンル別のソート状態)。これで全体の1/3ぐらいです。

プロパティ

.NETのForm1のプロパティウィンドウ

じゃあ、従来のVBではFormのプロパティの数とかはなんぼあんねん!と言われると確認していないので把握していませんが、 とにかく増えています。まずはこの図でプロパティをざっとご覧になってください。 いくつか目を引くものがあります。まずはMaximizeBoxMinimizeBoxに注目してもらうと、 先の4章で書いた名前のフルスペル化の波はここまで来ているのがわかります。

他には、

などが特徴的でしょう。 また、この図に載っていない分では、 などがあります。

メソッド

メソッドもいろいろと増えています。例えば、TextBoxやListBoxでは、以下のようなメソッドが目新しいでしょう。 (新規メソッドすべてではありません。一部だけです。)

  1. TextBox
  2. ListBox

イベント

プロパティが増えたのと同様にイベントもたくさん増えました。 例えば、Mouse系イベント一つとっても、従来はMouseDown、MouseMove、MouseUpの3しかありませんでしたが、この3つの他に、 MouseWheel、MouseEnter、MouseHover、MouseLeaveが増えました。

これにより標準でマウスのホイールは扱えますし、コントロール上にマウスが来たときに何らかの変化を起こしたいといったニーズも 簡単に実現できるようになっています。他にもイベントが大量に増えていますが、すべては紹介しきれませんので、おいおい紹介していくことになるでしょう。


ホーム > KEN's .NET > [第1回] 特集!VB.NET初体験!

[e-mail] yone_ken00@hotmail.com