この記事について
作成の経緯
新人研修で3ヶ月間Javaをやってきたけれども、配属先部署で使う言語はVisual Basic .NETだったので新しく学ぶ必要が生じた。
しかし、「JavaからVB.NETへ移行」というケースはそんなにないのか(今ならC#あたりが普通…?)、文法の比較などを細かくしているサイトが見つからなかったため、自分で書いてみることにした。
対象者・目的
- Javaの書き方やプログラミングの諸概念は一通り理解している
- これからVB.NETでもプログラムを書けるようになりたい
という人(まあ自分と数名の同期だけれど)にJavaとVB.NETの比較対象リファレンスを提供する。
環境
- Windows 10
- Visual Studio 2019
- .NET Framework 4.7.2
といっても、環境に依存するようなコードはほぼないはず。
記述上の注意
- Visual Basic .NET(VB.NET)のことは、以下単に「VB」と呼ぶ。
- 同じセクションにあるJavaとVBのコードは、基本的に同じ処理になるようにしている。
参考文献(総合)
- 羽山 博『基礎 Visual Basic 2019』(株式会社インプレス、2019年)
- VBを学習する上でお世話になっている教本。Javaなど他の言語を知っていれば、フルタイム×1週間くらいで読めてしまうと思われる。
-
Java屋さんからVB.netプログラマになるために - Qiita
- Javaの視点からVBを見た数少ない記事。
- Visual Basic のドキュメント - はじめに、チュートリアル、リファレンス。 | Microsoft Docs
コードの基本構造
main
public class Main {
public static void main(String[] args) {
System.out.println("Hello Java!");
int a; String b; double c;
}
}
- ブロックは
{}
で区切られる -
public
などの修飾子は小文字 -
;
で文を終える(改行それ自体は意味をもたない)
Public Class Form1
Private Sub ShowMessage(sender As Object, e As EventArgs) _
Handles Button1.Click
Console.WriteLine("Hello VB!")
Dim a As Integer : Dim b As String : Dim c As Double
End Sub
End Class
- ブロックは
(修飾子) Class
〜End Class
のように分けられる - 行の終わりは文(ステートメント)の終わり。
- 長い文中で意図的に改行させたいときは、行継続文字
_
を入れる - ただし、VB2010からは、特定の条件下で行継続文字がなくても改行できるようになった(暗黙の行継続)。
- 詳しいルールはVisual Basic 2010の新機能 - @ITを参照
- 長い文中で意図的に改行させたいときは、行継続文字
- 1行の中に複数のステートメントを入れたいときは、
:
で区切る。
コメント
// 単数行コメント
/*
* 複数行コメント
*/
' 単数行コメント
※VBに複数行コメントはない
ドキュメンテーションコメント
専用ツールでAPIドキュメントを生成したり、メソッド名上マウスオーバーで説明を表示したりできるやつ。
-
Java: Javadoc形式で記述する。
/**
~*/
- Eclipseでは、対象メンバにカーソルを当ててから Alt+Shift+J で生成できる
/**
* 引数で指定された2つの整数をかけ算し、その結果を返す。
* @param a かける数1
* @param a かける数2
* @return かけ算の結果
*/
public static int doCalc(int a, int b) {
return a * b;
}
-
VB: XMLで記述する。
'''
- Visual Studioでは、 対象メンバのすぐ上の行で
'''
と打つと生成できる。
- Visual Studioでは、 対象メンバのすぐ上の行で
''' <summary>
''' 引数で指定された2つの整数をかけ算し、その結果を返す。
''' </summary>
''' <param name="a">かける数1</param>
''' <param name="b">かける数2</param>
''' <returns>かけ算の結果</returns>
Public Shared Function DoCalc(a As Integer, b As Integer) As Integer
Return a * b
End Function
参考
ファイル・フォルダ構成
※一部省略あり
Java (Eclipse)の例
- JavaProject
- bin
- package
-
Main.class
(ビルドされたJavaバイトコード)
-
- package
- src
- package
-
main.java
(ソースコード)
-
- package
- lib
- doc
-
.project
(Eclipseプロジェクトファイル) .settings
.classpath
- bin
VB.NET Windows フォーム アプリケーション(Visual Studio)の例
- VisualStudioSolution
-
VisualStudioSolution.sln
(VSソリューションファイル) - FirstProject
-
FirstProject.vbproj
(VBプロジェクトファイル) - bin
- Debug
-
FirstProject.exe
(ビルドされたデバッグ用実行ファイル)
-
- Release
- Debug
- My Project
- obj
App.config
-
Form1.vb
(ソースコード[動作]) -
Form1.Designer.vb
(ソースコード[デザイン])
-
- SecondProject
- (FirstProjectと同様)
-
Visual Studioでは、複数のプロジェクトをソリューションとしてまとめることができる。(Eclipseでもワーキング・セットというものもあるが)
変数
データ型分類
- Java
- 基本型(
byte
,short
,int
,long
,float
,double
,char
,boolean
) - 参照型(
String
など)
- 基本型(
- VB
- 値型(
Byte
,Short
,Integer
,Long
,Single
(float相当),Double
,Decimal
(10進型),Char
,Boolean
,Date
など) - 参照型(
String
など)
- 値型(
日付型は、Javaではjava.util.Date
、java.util.Calender
、java.time
などの標準APIを使う必要がある(つまり必然的に参照型になる)。しかしVBでは、日付・時刻を管理できるDate
型を標準で用意している。
宣言・アクセス修飾
int number; // package private
String message; // package private
public int publicNumber;
private String privateMessage;
Dim Something ' Private
Dim Number As Integer ' Private
Dim Message As String ' Private
Public PublicNumber As Integer
VB標準設定では、変数の宣言時に型の指定を省略することができる。その場合、初期値のデータ型に従って自動的に変数のデータ型も決められる(型の推定)。初期値がない場合はObject型とみなされる。Option Strict On
にすると、型の推定は無効になる。
変数名の規則
文字 | Java | VB | 備考 |
---|---|---|---|
半角英数字 | ○ | ○ | |
日本語文字 | ○ | ○ | もちろんあまり推奨されない |
_ |
○ | ○ | アンダースコア |
& |
○ | × | |
先頭が数字 | × | × |
初期化
int number = 100;
String message = "Hello";
Dim Number As Integer = 100
Dim Message As String = "Hello"
Dim Pi = 3.14 ' 自動的にDouble型として扱われる
Dim BlankNumber As Integer ' 初期値は自動的に「0」になる
Dim BlankMessage As String ' 初期値は自動的に「Nothing」になる
定数宣言
final int MAX_STOCK = 100;
public static final String VERSION_ID = "v1.0.1-RELEASE";
Const MAX_STOCK As Integer = 100
Const VERSION_ID As String = "v1.0.1-RELEASE" ' ConstステートメントではSharedは使えない
参考
演算子
算術演算子
機能 | Java | VB.NET | 備考 |
---|---|---|---|
加算 | a + b |
a + b |
|
減算 | a - b |
a - b |
|
乗算 | a * b |
a * b |
|
除算 | a / b |
a / b |
|
整数除算(商) | N/A | a \ b |
[VB] aとbはどちらも整数型でなければならない。23 \ 5 の結果は4 になる |
剰余(余り) | a % b |
a Mod b |
23 % 5 ないし 23 Mod 5 の結果は3 になる |
累乗 | (演算子としてはなし) | a ^ b |
VBの^ は算術演算子の中で優先順位が最も高いことに注意 |
インクリメント |
++a または a++
|
N/A | VBではa += 1 などど書くしかない |
インクリメント |
--a または a--
|
N/A | VBではa -= 1 などど書くしかない |
整数同士の除算
Javaでは、割られる数a
と割る数b
の両方が整数だと、結果の小数点以下が切り捨てられ、整数になる。これは代入先がdouble
型などの変数であっても変わらない。
double x;
x = 23 / 5; // xは4.0になる
少なくとも片方が小数(倍精度浮動小数点数)だと、結果も小数になる。
double x;
x = 23 / 5.0 // xは4.6になる
一方、VBではできるだけ精度が落ちないように演算が行われる。
Dim x As Double
x = 23 / 5 ' xは4ではなく4.6になる
VBでもJavaのように整数同士の除算をしたい場合に、\
演算子を使う。
Dim x As Double
x = 23 \ 5 ' xは4になる
Javaにおける累乗
Javaでは、 java.lang.Math.pow(a, b)
を使う。
第1引数a
が底、第2引数b
が指数(つまりVBでいうところの a ^ b
)。
代入演算子
機能 | Java | VB.NET | 備考 |
---|---|---|---|
そのまま代入 | a = b |
a = b |
|
加算結果を代入 | a += b |
a += b |
|
減算結果を代入 | a -= b |
a -= b |
|
乗算結果を代入 | a *= b |
a *= b |
|
除算結果を代入 | a /= b |
a /= b |
|
整数除算の結果を代入 | N/A | a \= b |
|
剰余(余り)を代入 | a % b |
N/A | [VB]Modに対応するものはない |
(ビット演算系は省略)
比較演算子
機能 | Java | VB.NET | 備考 |
---|---|---|---|
aはbよりも小さい | a < b |
a < b |
|
aはb以下 | a <= b |
a <= b |
|
aはbよりも大きい | a > b |
a > b |
|
aはb以上 | a >= b |
a >= b |
|
aはbに等しい | a == b |
a = b |
VBでは= は1個 |
aはbに等しくない | a != b |
a <> b |
論理演算子
以下の表ではA
やB
は条件式(True/Falseを返す式)を表す。
論理 | 機能 | Java | VB.NET |
---|---|---|---|
論理積(AND) | AかつB | N/A | A And B |
論理積(AND) | AかつB(短絡評価) | A && B |
A AndAlso B |
論理和(OR) | AまたはB | N/A | A Or B |
論理和(OR) | AまたはB(短絡評価) | A && B |
A OrElse B |
論理積(NOT) | Aでない | !A |
Not A |
排他的論理和(XOR) | AまたはB、しかしAかつBではない | ^A |
A Xor B |
短絡評価:
AがFalseなら条件式全体がFalseになることが確定するので、Bを評価せずに先へ進むこと。
このとき、Bに何らかのメソッドが書いてあっても実行されない。
これを利用して、AがTrueにならないとエラーになる式をBに書くことができる。
例:If Integer.TryParse(str, num) AndAlso num < 5 Then ...
連結演算子
Javaでは文字列の連結に +
を使うが、VBでは &
を使う。
VBでも+
で文字列連結をすることは可能だが、片方が文字列型でない場合に意図しない結果となったり、エラーになる可能性があるため、Microsoftは&
の使用を推奨している。
演算子の参考ページ
型変換
条件分岐
if文 / Ifステートメント
if (age < 20) canBuyAlcohol = true;
if (age < 13) {
fareType = "child";
} else if (age < 18) {
fareType = "student";
} else {
fareType = "adult";
}
If age < 20 Then canBuyAlcohol = True ' 1行ならばEnd Ifはいらない
If age < 13 Then
FareType = "child"
ElseIf age < 18 Then
FareType = "student"
Else
FareType = "adult"
End If
VBでは、次のように「:
」を使って複数のステートメントを1行に書くことも可能。
If 20 < age Then FareType = "adult" : CanBuyAlcohol = true Else CanBuyAlcohol = false
Switch / Select Caseステートメント
1つの値と一致させる
switch (num) {
case 1:
gender = "男性";
break;
case 2:
gender = "女性";
break;
case 3:
gender = "その他";
break;
default:
gender = "未回答";
break;
}
switch文の式(上記のnum
)は、基本型+String型(Java SE 7以降)のみ。
Select Case Num
Case 1
Gender = "男性"
Case 2
Gender = "女性"
Case 3
Gender = "その他"
Case Else
Gender = "未回答"
End Select
複数の値に一致させる
switch (phoneNumberPrefix) {
case 090:
case 080:
case 070:
isMobile = true;
break;
default:
isMobile = false;
break;
}
Select Case PhoneNumberPrefix
Case 090, 080, 070
IsMobile = true
Case Else
IsMobile = false
End Select
値の範囲を指定する
// JavaのSwitch文ではできない(やるとしても別の変数を噛ませるしかない)
Select Case MonthNumber
Case 3 To 5
Season = "春"
Case 6 To 8
Season = "夏"
Case 9 To 11
Season = "秋"
Case Else
Season = "冬"
End Select
比較演算子を使う
// JavaのSwitch文ではできない(素直にif文使った方が良い)
Select Case Score
Case Is < 60
Grade = "F"
Case Is < 70
Grade = "C"
Case Is < 80
Grade = "B"
Case Is < 90
Grade = "A"
Case Else
Grade = "S"
End Select
繰り返し
for文 / Forステートメント
for (int i = 0; i <= 9; i++) {
System.out.println(i + "回目の繰り返し処理です");
}
For i As Integer = 0 To 9 Step 1 ' 増分値1の場合、Stepは省略可能
Debug.WriteLine(i & "回目の繰り返し処理です")
Next
どちらの言語でも、For文の初期化式内でループカウンタを宣言するのではなく、For文の外で宣言した変数を使うこともできる。その場合、For文を抜けてもその変数を使うことができる。
int i;
for (i = 0; i <= 9; i++) {
System.out.println(i + "回目の繰り返し処理です");
}
System.out.println(i + "回繰り返されました");
Dim i As Integer
For i = 0 To 9 Step 1 ' 増分値1の場合、Stepは省略可能
Debug.WriteLine(i & "回目の繰り返し処理です")
Next
Debug.WriteLine(i & "回繰り返されました")
拡張for文 / For-Eachステートメント
int[] scoreArray = {70, 80, 90};
// 通常のfor文
for (int i = 0; i < scoreArray.length(); i++) {
System.out.println(scoreArray[i]);
}
// 拡張for文
for (int score : scoreArray) {
System.out.println(score);
}
Dim ScoreArray() As Integer = {70, 80, 90}
' 通常のfor文
For i As Integer = 0 To UBound(ScoreArray)
Debug.WriteLine(ScoreArray(i))
Next
' For Eachステートメント
For Each score As Integer In ScoreArray
Debug.WriteLine(score)
Next
while文 / While-End Whileステートメント
条件がtrueである限り実行し続ける。
int i = 0;
while (i < 10) {
System.out.println(i + "回目の繰り返し処理です");
i++;
}
Dim i As Integer = 0
While i < 10
Debug.WriteLine(i & "回目の繰り返し処理です")
i += 1
End While
※このサンプルではWhileよりもForのほうが適している
do-while文 / Do-Loopステートメント
後判断型(1回は実行される)
Random rd = new Random();
int num = 0;
do {
num = rd.nextInt(100) + 1;
System.out.println(num);
} while (num % 2 == 0);
Dim rd As Random = new Random()
Dim Num As Integer = 0
Do
Num = rd.Next(1, 100)
Debug.WriteLine(Num)
Loop While Num Mod 2 = 0
VBでは、Loop While 条件
(条件がfalseになるまで繰り返す)のほか、Loop Until 条件
(条件がtrueになるまで繰り返す)というのも使える。
Dim rd As Random = new Random()
Dim Num As Integer = 0
Do
Num = rd.Next(1, 100)
Debug.WriteLine(Num)
Loop Until Num Mod 2 <> 0
Until
以下の条件が逆転しているが、DoLoopWhile.vb
とDoLoopUntil.vb
はどちらも同じ処理になる。
前判断型(1回も実行されない可能性がある)
Dim i As Integer = 0
Do While i < 10
Debug.WriteLine(i & "回目の繰り返し処理です")
i += 1
Loop
Dim i As Integer = 0
Do Until i >= 10
Debug.WriteLine(i & "回目の繰り返し処理です")
i += 1
Loop
ループを抜ける
-
Java:
break;
-
VB:
Exit Do
、Exit For
、Exit While
途中で次の繰り返しに進む
-
Java:
continue;
-
VB:
Continue Do
、Continue For
、Continue While
配列
宣言
カッコの中で指定する数字の意味が違う点に注意。
int[] numArray = new int[5];
インデックス 0
, 1
, 2
, 3
, 4
の合計5個の要素を持った配列になる。
[n]
で指定するのは配列の要素数。
Dim NumArray(4) As Integer
インデックス 0
, 1
, 2
, 3
, 4
の合計5個の要素を持った配列になる。
(n)
で指定するのはインデックスの最大値。
初期化
int[] numArray = { 10, 20, 30, 40, 50 };
Dim NumArray() As Integer = { 10, 20, 30, 40, 50 }
代入・利用
numArray[3] = 31;
int a = numArray[3];
NumArray(3) = 31
Dim a As Integer = NumArray(3)
多次元配列
int[][] numArray = new int[3][4];
double[][] doubleArray = { { 0.0, 0.1, 0.2 }, { 1.1, 2.2, 3.3, 4.4 } };
Dim NumArray(2, 3) As Integer
Dim DoubleArray(, ) As Double = { { 0.0, 0.1, 0.2 }, { 1.1, 2.2, 3.3, 4.4 } }
(, )
は一見するとインデックス最大値を入れ忘れているようにも見えるが、Javaでいう[][]
に相当するもの。
配列サイズの変更
Javaでは一度作った配列のサイズを変更することはできず、新たに配列を作ってそこに値を移し替えるしかない。
しかし、VBでは**ReDim
ステートメント**を使うことで配列のサイズを変更できる。
Dim NumArray(9) As Integer
' ...
ReDim Preserve NumArray(6)
Preserve
を付けると、元の要素の値が保持される(付けないと全ての要素が空になる)。
要素数を減らした場合、減らされた分の要素は削除される(上記例では、インデックス7
, 8
, 9
の3要素は削除される)。
配列の長さ(要素数)
-
Java
-
配列名.length
(要素数を返す) を使う。
-
int[] numArray = new int[5];
for (int i = 0; i < numArray.length; i++) {
numArray[i] = i;
}
// 配列の中身は {0, 1, 2, 3, 4} になる
-
VB:
-
配列名.Length
(要素数を返す)を使う。 - 繰り返しで全要素を処理する場合は、
UBound(配列名)
(インデックスの最大値を返す)を使う。- For文の
To
は<
ではなく<=
の意味。 - したがって、
0 To 配列名.Length
と書くと、最終回で配列の長さを突き抜けてしまいSystem.IndexOutOfRangeException
になる。 - どうしても
UBound()
を覚えたくなければ、配列名.Length - 1
でもいけなくはないが…
- For文の
-
Dim NumArray(4) As Integer
For i As Integer = 0 To UBound(NumArray)
NumArray(i) = i
Next
' 配列の中身は {0, 1, 2, 3, 4} になる
メソッド / プロシージャ
概念の整理(整理し切れていない)
基本的に、「メソッド」=「プロシージャ」だと思っても実用上は困らない。
Javaでは「メソッド」しか出てこないのに対して、VBではどちらの単語も登場する。やっていることは同じ「一連の処理をまとめる」ということだが、「メソッド」は、プロシージャの中でもその所属元を意識している言葉、らしい。
「オブジェクト」が持つ「性質」(フィールド)と「機能」(メソッド)、という感じ。
ただ、英語で "what is the difference between a method and a procedure in visual basic" ってググると、"method vs procedure" じゃなくて "function vs procedure" って書いてあるページばかりがヒットする(method = function?)
このあたりはプログラム言語の歴史(関数 function とか サブルーチン subroutine)にかかわってきそう。
参考
用語の比較
対象 | Java | VB |
---|---|---|
戻り値を返さない処理 | メソッド(void ) |
Sub プロシージャー |
戻り値を返す処理 | メソッド(void 以外) |
Function プロシージャー |
クラスフィールドの読み書きをする処理 |
getter /setterメソッド
|
Property プロシージャー |
個々のインスタンスに属する処理 | インスタンスメソッド | (普通のSub /Function プロシージャー) |
クラス全体に属する処理 |
static メソッド |
共有(Shared )メソッド |
イベントに応じた処理 | N/A | イベントハンドラー(Subプロシージャーの一形態) |
Subプロシージャー
戻り値を返さない 処理。(直接の戻り値がないだけなので、参照渡しを使って呼び出し元に存在する変数やオブジェクトを書き換え、データを返すようなことは可能)
-
Java:
アクセス修飾子 [static] void 名前(型名 引数名, ...) {
~}
public void showMessage(int a, int b) {
System.out.println(a + b);
}
-
VB:
アクセス修飾子 [Shared] Sub 名前(引数名 As 型名, ...)
~End Function
- イベントハンドラーもここに属する(後ろに
Handles
句が付くやつ)
- イベントハンドラーもここに属する(後ろに
Public Sub ShowMessage(Str1 As String, Str2 As String)
Debug.WriteLine(a + b)
End Sub
Functionプロシージャー
戻り値を返す処理。
-
Java:
アクセス修飾子 [static] 戻り値の型 名前(型名 引数名, ...) {
~}
-
return
で戻り値を指定する
-
public int doCalc(int a, int b) {
return a * b;
}
-
VB:
アクセス修飾子 [Shared] Function 名前(引数名 As 型名, ...) As 戻り値の型
~End Function
-
Return
で戻り値を指定する
-
Public Function DoCalc(a As Integer, b As Integer) As Integer
Return a * b
End Function
Propertyプロシージャー
→ クラスの項目で解説
プロシージャーを途中で抜ける
public void showMessage() {
if (errFlag) {
return; // 実はvoidメソッドでもこれで抜けられる
} else {
System.out.println("処理成功")
}
}
public int doCalc(int a, int b) {
int result = a * b;
if (result > 10) {
return 0; // 値を返さずに抜けることは許されない
} else {
return result;
}
}
Public Sub ShowMessage()
If ErrFlag Then
Exit Sub ' VBではExit Sub
Else
Debug.WriteLine("処理成功")
End Sub
Public Function DoCalc(a As Integer, b As Integer) As Integer
Dim result As Integer = a * b
If (result > 10) Then
Exit Function ' 戻り値がInteger型なので0を返す
ElseIf (result > 50) Then
DoCalc = result + 1
Exit Function ' 変数DoCalcに設定した値を返す
Else
Return result
End If
End Function
Javaだとreturn
せずにvoid以外のメソッドを抜けることは不可能だが、VBのFunctionプロシージャーではできてしまう。
ただし、戻り値の型によってはぬるぽ例外を発生させるなど、予期しない動作を招く原因になりかねないので、必ずReturn
すべきと思われる。
可変長引数
-
Java: 引数を
(データ型... 変数名)
とする- 当該メソッド内では、配列変数のように扱うことができる
- 他の引数も指定する場合、可変長引数は引数リストの最後に置かなければならない
public static int getSum(int... numbers) {
int sum = 0;
for (int i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
return sum;
}
-
VB:
(ParamArray 変数名 As データ型[])
とする- 性質はJavaと同じ。
Public Shared Function GetSum(ParamArray Numbers As Integer[]) As Integer
Dim Sum As Integer = 0
For i As Integer = 0 To UBound(Numbers)
Sum += Numbers(i)
Next i
Return sum;
End Function
可変長引数の参考文献
オブション引数
呼び出し時に省略可能な引数。
-
Java: (たぶん)言語仕様として持っていない。
- Java 8 から導入された
Optional
型は、全く違う概念なので混同しないこと。
- Java 8 から導入された
-
VB:
(Optional 変数名 As データ型 = 既定値)
とする- 呼び出し時に省略された場合、既定値が渡されたものとみなされる。
- なので既定値は必ず指定しておく必要がある。
- Optionalを指定した引数移行のすべての引数は、Optionalでなければならない(省略できない引数を全て書いた後、Optional引数を書く)
- Optional引数を複数設けること自体はOK。
Public Shared Function Calc(Num1 As Integer, Num2 As Integer, Optional CalcMethod As Integer = 0)
If CalcMethod = 0 Then
Return Num1 + Num2
ElseIf CalcMethod = 1 Then
Return Num1 - Num2
ElseIf CalcMethod = 2 Then
Return Num1 * Num2
ElseIf CalcMethod = 3 Then
Return Num1 / Num2
Else
Return 0
End If
End Function
この例では、Calc(5, 10)
のように呼び出した場合、CalcMethod = 0
のパターン(つまり足し算)が実行される。
返り値として複数の値を受け取る
- Java: クラスにまとめて、そのオブジェクトを返すしかない。
public static Result getResult(int a, int b) {
Result result = new Result();
result.setSum(a + b);
result.setDiff(a - b);
result.setProduct(a * b);
result.setQuotient((double) a / b);
Return result;
}
public Class Result {
int Sum;
int Diff;
int Product;
double Quotient;
// getter / setter
}
-
VB: タプルを利用して複数の値を返すことができる
- タプル:その場で複数の変数を1つにまとめたもの
- 臨時のクラスを作る、というイメージだと分かりやすいだろうか
Public Sub Main()
' タプルを名前付きで宣言
Dim Result As (Sum As Integer, Diff As Integer, Product As Integer, Quotient As Double)
Result = GetResult(5, 10)
' タプルに入った値を利用
Debug.WriteLine(Result.Sum)
Debug.WriteLine(Result.Diff)
Debug.WriteLine(Result.Product)
Debug.WriteLine(Result.Quotient)
End Sub
' タプルを返すFunctionプロシージャー
Public Shared Function GetResult(a As Integer, b As Integer) As (Integer, Integer, Integer, Double)
Return (a + b, a - b, a * b, a / c)
End Function
エントリポイント
プログラムが起動されたときに、最初に実行されるメソッド。
Javaはmainと名の付くメソッドが必ずエントリポイントになるが、VBではそうとは限らない。Windows Formsプロジェクトを作成すると、最初に作成したフォームがエントリポイントになる。これを変更する方法については、JavaのmainメソッドをVB.NETで作成してみる! | ライズウィルスタッフブログが詳しい。
クラス
構成
-
Javaクラス
public class Main{ }
- フィールド
- メソッド
-
getter
/setter
メソッド
-
※JavaBeansの形式に従った例。
public class JavaClass {
// フィールド(オブジェクトの状態/性質を示すもの)
private int field;
// メソッド(オブジェクトの動作・振る舞いを示すもの)
public void method(){
// ...
}
// メソッド > getter(カプセル化されているprivateフィールドの読み取り機能を提供)
public int getField() {
return field;
}
// メソッド > setter(カプセル化されているprivateフィールドへの書き込み機能を提供)
public void setField(int value) {
this.field = value;
}
}
-
VBクラス
Public Class Main ... End Class
- フィールド(メンバ変数)
- プロパティとの区別のために、
_
を接頭辞として付ける場合がある
- プロパティとの区別のために、
- プロパティ
-
Get
プロシージャー -
Set
プロシージャー
-
- プロシージャ(メソッド)
- イベント
- フィールド(メンバ変数)
Public Class VBClass
' フィールド(メンバー変数)
Dim _field As Integer
' プロパティ
Property field() As Integer
Get
Return _field
End Get
Set(ByVal value As Integer)
_field = value
End Set
End Property
' プロシージャー
Public Sub Procedure()
' ...
End Sub
End Class
プロパティについてもっと詳しく
基本
プロパティは、Javaでいうところのgetter/setterメソッドをまとめたもの(Getプロシージャ・Setプロシージャのうち片方だけを実装することもできる)。
Javaと異なるのは、プロパティは当該クラスの外からはフィールドのように扱われるという点である。
たとえば、上記サンプルコード JavaClass.java
の プライベートフィールド field
に他のクラスからアクセスするときには、次のようなコードを書く必要がある。
public class Main {
public static void main(String[] args) {
JavaClass jc = new JavaClass();
// 以下2行はコンパイルエラーになる
int num = jc.field;
jc.field = 100;
// 代わりに、こう書く
int num = jc.getField();
jc.setField(100);
}
}
このように、オブジェクト変数名.フィールド名
ではアクセスが拒否されるので、代わりにgetterメソッドの返り値としてフィールドの内容を受け取ったり、setterメソッドに値を引数として渡すことでフィールドの内容を書き換えるというやり方になる。
これと同じような動きをVBで書くと、こうなる。
Public Class Main
Public Shared Sub Main
Dim vbc As New VBClass()
Dim num As Integer = vbc.field 'Get呼び出し
vbc.field = 100 'Set呼び出し
End Sub
End Class
プロパティ名をフィールドのように書くことで、そのプロパティに定義されたGet/Setプロシージャーが暗黙的に呼び出される。
自動実装プロパティ
なお、単に値を返す/書き込むだけのプロパティであれば、自動実装プロパティを使うことでコードを簡略化できる。
Public Class AutoImplProperty
Public Property Name As String
Public Property Owner As String = "DefaultName"
Public Property Items As New List(Of String) From {"M", "T", "W"}
Public Property ID As New Guid()
End Class
(自動実装プロパティ - Visual Basic | Microsoft Docs より)
このとき、プロパティ名に_
を付けた隠しPrivateフィールド(バッキング フィールド)が自動的に作成される。上記の例では、_Name
, _Owner
, _Items
, _ID
というバッキングフィールドが作成される(従って、自分でこれらと同じ名前のフィールドを宣言するとコンパイルエラーになる)
プロパティ:フィールド = 1:n もOK
また、プロパティはフィールドと1対1で対応している必要はない。言い換えると、複数のフィールドから値を拾ってきて、連結して1つのフィールドのように扱うこともできる。また、1つのまとまった値を受け取り、実際には2つ以上のフィールドに分割して格納する、ということもできる。(もちろんそれに見合ったGet/Setプロシージャを定義しておく必要はある)。
Microsoft Docsにわかりやすい例があったので、引用する(クラス内のメンバであることが分かりやすいよう、Public Class
~ End Class
を付加している)。
次のプロパティは、フル ネームを 2 つの構成要素名 (名と姓) として格納します。 呼び出し元のコードが fullName を読み取ると、Get プロシージャが 2 つの構成要素名を結合し、フル ネームを返します。 呼び出し元のコードが新しいフル ネームを割り当てると、Set プロシージャがそれを 2 つの構成要素名に分割することを試みます。 スペースが見つからない場合は、すべてが名として格納されます。.
Property プロシージャ - Visual Basic | Microsoft Docs
Public Class CombinedProperty
Private firstName As String
Private lastName As String
Property fullName() As String
Get
If lastName = "" Then
Return firstName
Else
Return firstName & " " & lastName
End If
End Get
Set(ByVal Value As String)
Dim space As Integer = Value.IndexOf(" ")
If space < 0 Then
firstName = Value
lastName = ""
Else
firstName = Value.Substring(0, space)
lastName = Value.Substring(space + 1)
End If
End Set
End Property
End Class
呼び出し側:
fullName = "MyFirstName MyLastName"
MsgBox(fullName)
その他、プロパティとメンバ変数の違いについては以下のページも参照。