Linux(mono)でVB、ポリモーフィズム

プロパティがおぼろげに分かってきたところで、次はポリモーフィズムを学習したいと思います。
また犬クラス(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$

動きました。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA