クラスはいつ使うのか
商品名と価格、口座名義と残高のように、常に一緒に扱う値とその操作が増えたとき、クラスにまとめると関係が明確になります。小さな計算だけならFunctionで十分です。
クラスにする目安
- 一緒に扱う複数の値がある
- その値への操作が複数ある
- 不正な状態を防ぐルールがある
クラスとインスタンス
Product.vbVB.NET
Public Class Product
Public ReadOnly Property Name As String
Public ReadOnly Property Price As Integer
Public Sub New(name As String, price As Integer)
Me.Name = name
Me.Price = price
End Sub
Public Function Total(count As Integer) As Integer
Return Price * count
End Function
End ClassMainから使うVB.NET
Dim book As New Product("VB入門", 2000)
Dim pen As New Product("ペン", 120)
Console.WriteLine(book.Total(2))
Console.WriteLine(pen.Name)実行結果OUTPUT
4000
ペンNew Product(...)ごとに別のインスタンスができます。Meは現在のインスタンス自身です。
プロパティで状態を守る
コンストラクターで検証し、外から変更不要なプロパティをReadOnlyにすれば、不正な商品を作りにくくできます。
初期化時に検証VB.NET
Public Sub New(name As String, price As Integer)
If String.IsNullOrWhiteSpace(name) Then
Throw New ArgumentException("商品名は必須です", NameOf(name))
End If
If price < 0 Then
Throw New ArgumentOutOfRangeException(NameOf(price))
End If
Me.Name = name
Me.Price = price
End SubPrivateなフィールドはクラス内部だけから使えます。値を無条件に公開するのではなく、必要な操作をメソッドとして用意します。
継承は「一種」である関係に使う
Inheritsで既存クラスを引き継げます。次のように「DogはAnimalの一種」と自然に言える関係で使います。
継承VB.NET
Public MustInherit Class Animal
Public MustOverride Function Speak() As String
End Class
Public Class Dog
Inherits Animal
Public Overrides Function Speak() As String
Return "ワン"
End Function
End Class
' Main内
Dim animal As Animal = New Dog()
Console.WriteLine(animal.Speak())実行結果OUTPUT
ワン組み合わせも検討 単に別クラスの機能を使いたいだけなら、フィールドやプロパティとして保持するほうが変更しやすい場合があります。
インターフェースで約束を表す
インターフェースは「この操作を持つ」という約束です。実装を差し替えられるため、通知方法や保存先の違いを分離できます。
通知の約束VB.NET
Public Interface INotifier
Sub Send(message As String)
End Interface
Public Class ConsoleNotifier
Implements INotifier
Public Sub Send(message As String) Implements INotifier.Send
Console.WriteLine($"通知: {message}")
End Sub
End Classミニ課題:銀行口座
口座名義と残高を持つBankAccountを作り、預け入れと引き出しをメソッドにしてください。0以下の金額や残高を超える引き出しは例外にし、初期残高0から1000円を預けて400円を引くと600円になることを確認します。