プロパティがおぼろげに分かってきたところで、次はポリモーフィズムを学習したいと思います。
また犬クラス(Dog)を追加しました。動物クラス(Animal)にもあるTalkメソッドを実装しています。
takk@deb9:~/vbtest$ cat -n test.vb 1 Imports System.Console 2 3 Public Class Animal 4 Private _classname As String = "哺乳類" 5 Public ReadOnly Property Classname() As String 6 Get 7 Return _classname 8 End Get 9 End Property 10 Private _name(2) As String 11 Public Property Name(idx As Integer) As String 12 Get 13 Return _name(idx) 14 End Get 15 Set(ByVal value As String) 16 If value <> "" Then 17 _name(idx) = value 18 Else 19 WriteLine("名前をつけてください") 20 End If 21 End Set 22 End Property 23 24 Public Sub Talk() 25 End Sub 26 27 Sub WhatIsThis() 28 WriteLine( _classname & "です" ) 29 For Each m As String in _name 30 If m <> Nothing Then 31 WriteLine( "名前は" & m & "と言います" ) 32 End If 33 Next 34 End Sub 35 End Class 36 37 Public Class Dog : inherits Animal 38 Public Sub Talk() 39 WriteLine( "『わんわん』" ) 40 End Sub 41 End Class 42 43 Public Class TestClass 44 <STAThread()> _ 45 Shared Sub Main() 46 Dim dog As New Dog() 47 dog.Name(0) = "シロ" 48 dog.WhatIsThis() 49 dog.Talk() 50 End Sub 51 52 End Class takk@deb9:~/vbtest$
ビルドして実行すると、
takk@deb9:~/vbtest$ vbnc test.vb ~省略~ takk@deb9:~/vbtest$ mono test.exe 哺乳類です 名前はシロと言います 『わんわん』 takk@deb9:~/vbtest$
問題ないですね。
次は、動物クラスを継承して人間クラスも作りました。
43 Public Class Human : inherits Animal 44 Public Sub Say() 45 WriteLine( "『こんにちは』" ) 46 End Sub 47 End Class
呼び出し部分は、こんな感じ。
49 Public Class TestClass 50 <STAThread()> _ 51 Shared Sub Main() 52 Dim dog As New Dog() 53 dog.Name(0) = "シロ" 54 dog.WhatIsThis() 55 dog.Talk() 56 57 Dim human As New Human() 58 human.Name(0) = "モモ" 59 human.WhatIsThis() 60 human.Talk() 61 End Sub 62 End Class
ビルド、実行。
takk@deb9:~/vbtest$ vbnc test.vb ~省略~ takk@deb9:~/vbtest$ mono test.exe 哺乳類です 名前はシロと言います 『わんわん』 哺乳類です 名前はモモと言います takk@deb9:~/vbtest$
あれ、何かおかしいです。人間が喋ってません。
人間クラスを作るとき、Talkメソッドが、Sayメソッドで実装してしまったのが原因です。Talkメソッドは動物クラスに空のメソッドとして存在するので、何も処理されなかったんですね。
43 Public Class Human : inherits Animal 44 Public Sub Say() 45 WriteLine( "『こんにちは』" ) 46 End Sub 47 End Class
こんな間違いを起こさないために、Talkメソッドを強制的にオーバーライドさせることにします。
動物クラスでTalkメソッドをMustOverrideをつけて抽象化します。End Subは要りません。
23 24 Public MustOverride Sub Talk() 25
サブクラスでは、TalkメソッドにOverridesをつけます。
36 Public Class Dog : inherits Animal 37 Public Overrides Sub Talk() 38 WriteLine( "『わんわん』" ) 39 End Sub 40 End Class 41 42 Public Class Human : inherits Animal 43 Public Overrides Sub Talk() 44 WriteLine( "『こんにちは』" ) 45 End Sub 46 End Class
では、ビルド。
takk@deb9:~/vbtest$ vbnc test.vb Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.7 - tarball) Copyright (C) 2004-2010 Rolf Bjarne Kvinge. All rights reserved. Assembly 'test, Version=0.0, Culture=neutral, PublicKeyToken=null' saved successfully to '/home/takk/vbtest/test.exe'. Compilation successful Compilation took 00:00:00.5661270 takk@deb9:~/vbtest$
実行します。
takk@deb9:~/vbtest$ mono test.exe Unhandled Exception: System.TypeLoadException: Parent class vtable failed to initialize, due to: Type Animal has invalid vtable method slot 4 with method none assembly:/home/takk/vbtest/test.exe type:Animal member:(null) [ERROR] FATAL UNHANDLED EXCEPTION: System.TypeLoadException: Parent class vtable failed to initialize, due to: Type Animal has invalid vtable method slot 4 with method none assembly:/home/takk/vbtest/test.exe type:Animal member:(null) takk@deb9:~/vbtest$
なんてことでしょう。実行エラー。
そういえば、動物クラスに、MustInheritをつけるのを忘れてました。
3 Public MustInherit Class Animal 4 Private _classname As String = "哺乳類" 5 Public ReadOnly Property Classname() As String 6 Get 7 Return _classname 8 ~省略~
これでOKのハズです。
ビルド、実行。
takk@deb9:~/vbtest$ vbnc test.vb ~省略~ takk@deb9:~/vbtest$ mono test.exe 哺乳類です 名前はシロと言います 『わんわん』 哺乳類です 名前はモモと言います 『こんにちは』 takk@deb9:~/vbtest$
動きました。
コメント