3

オーバーロードがコンパイル時ポリモーフィズムと呼ばれ、オーバーライドがランタイム ポリモーフィズムと呼ばれるのはなぜですか? たとえば、次のコードを見てください。

Public Class Animal
    Public Overridable Overloads Sub Eat()
        MsgBox("Animal Eat no arguement")
    End Sub
    Public Overridable Sub Drink()
        MsgBox("Animal drink arguement")
    End Sub
End Class

Public Class Horse
    Inherits Animal
    Public Overloads Overrides Sub Eat()
        MsgBox("Horse Eat no arguement")
    End Sub
    Public Overloads Sub Eat(ByVal food As String)
        MsgBox("Horse Eat food arguement")
    End Sub
    Public Overloads Overrides Sub Drink()
        MsgBox("Animal drink arguement")
    End Sub
End Class

Public Class Form1

    Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim a1 As New Animal
        Dim a2 As Animal
        a2 = New Horse
        a1.Eat()
        a2.Eat("Fruit") 'line 6
    End Sub
End Class

6 行目では、プログラムがそのままの状態でコンパイル エラーが発生します。ただし、 Animal クラスに Eat(String) を追加すると、コンパイルされます。この背後にある理由は何ですか?

また、次の投稿の回答には、「Overloads キーワードはオプションですが、1 つのメソッドに使用する場合は、そのメソッドのすべてのオーバーロードに使用する必要があります。」 -vb-net のキーワード。問題の関数もオーバーライドする場合、これが当てはまるとは限りません。これは事実ですか?

インターフェイスでポリモフィズムを使用する大規模なプログラムを調べています。上記のクラスは、説明のための例として提供しています。

4

2 に答える 2

1

6行目は、プログラムが立っているため、コンパイル時エラーが発生します。ただし、 Animal クラスに Eat(String) を追加すると、コンパイルされます。この背後にある理由は何ですか?

これは、ベース クラス (Animal) シグネチャを変更するまで、型 Animal によって公開されたシグネチャには、文字列を含む Eat バージョンがないためです。ポリモーフィズムを使用すると、馬を動物タイプとして参照できますが、動物の署名を介してのみ参照できます (馬タイプにキャストしない限り)。したがって、Animal から継承されたが、eat("") を持たない別のタイプの Cat がある場合、VB があなたが言及したことを許可すると、コンパイラ エラーが発生します。

また、次の投稿の回答には、「Overloads キーワードはオプションですが、1 つのメソッドに使用する場合は、そのメソッドのすべてのオーバーロードに使用する必要があります。

オーバーライドはあなたが見つけた回避策を提供すると思いますが、100%確実ではありません。私は個人的には、入力を節約するために Overload をまったく使用していません。C# では Overload を使用していないためです。

于 2012-07-23T16:18:24.877 に答える
0

なぜ彼らがそれをコンパイル時またはランタイムポリモーフィズムと呼ぶのかわかりませんが、それがどのように機能するかを説明しようと思います:

クラスメンバーをオーバーライドすると、基本クラスのそのメンバーの実装が置き換えられます。これは、独自のクラスのメンバーをオーバーライドできないことを意味します。

これはコンパイルされません:

Public Class Animal
    Public Overridable Sub Eat()
        ' eat whatever
    End Sub
    Public Overrides Sub Eat()
        ' eat whatever
    End Sub
End Class

これコンパイルされます:

Public Class Animal
    Public Overridable Sub Eat()
        ' eat whatever
    End Sub
End Class

Public Class Horse : Inherits Animal
    Public Overrides Sub Eat()
        ' eat whatever, except meat
    End Sub
End Class

この例では、元の実装を、馬が肉を食べないようにする実装に置き換えました。これにより、タイプでこの制限が指定されていなくても、インスタンスがHorse肉製品を食べることができなくなります。Animalただし、独自の食品タイプを指定するには、文字列パラメーターを受け取るオーバーロードを追加する必要があります。

メンバーをオーバーロードすると、元の実装またはオーバーロード実装のいずれかを選択できます。同じクラス、またはこの基本クラスから継承するサブクラスのメンバーをオーバーロードできます。または両方のクラスでも。

これは機能します:

Public Class Animal
    Public Overloads Sub Eat()
        ' eat whatever
    End Sub
    Public Overloads Sub Eat(food as String)
        ' eat food
    End Sub
End Class

これも機能します:

Public Class Animal
    Public Overloads Sub Eat()
        ' eat whatever
    End Sub
End Class

Public Class Horse : Inherits Animal
    Public Overloads Sub Eat(food as String)
        ' eat food
    End Sub
End Class

結論

メンバーをオーバーライドすることにより、基本タイプの実装を効果的に無効にします。メンバーをオーバーロードすることにより、実装を追加して、どちらの実装も使用できるようにします。メンバーをオーバーライドできるのは1回だけですが、必要な回数だけメンバーをオーバーロードできます。

ガッチャ

型のインスタンスを作成し、Horseそれを型の変数に割り当てるとAnimal、基本クラスのメンバーのみが表示されますが、それらは引き続きHorse型の実装を使用します。これを回避するには、typeのインスタンスをtypeAnimalにキャストしますHorse

于 2013-01-10T15:04:03.840 に答える