1

次のような 3 つのクラスの階層があります。

`DrawingObject` > `RectangularDrawingObject` > `Rectangle`

DrawingObject次のメンバーがあります。

Protected Overridable Function ToXMLInternal(type As Type) As String

この関数を第 2 レベルのみ (つまりRectangularDrawingObject) に公開し、第 3 レベル (Rectangleなど) のクラスから隠したいので、次のようにシャドウしRectangularDrawingObjectます。

Private Shadows Function ToXMLInternal(type As Type) As String

ここで検討Privateしてください。シャドウを行ったので、基本バージョンは第 3 レベルのクラスにアクセスできなくなりました。また、非公開であるため、このバージョンもアクセスできないようにする必要があります。しかし、クラスでアクセスできます (第 1 レベル バージョン) Rectangle。どうしてこんなことに?回避策は何ですか?

編集:

ニコの答えについて:

RectangularDrawingObject の ToXMLInternal() は、外部から Rectangle にアクセスする場合でも有効です。

これは正しくありません。ToXMLInternal() はRectangle、せいぜい保護されているため、外部からアクセスする場合は利用できない/利用できないはずです。

Rectangle 内から ToXMLInternal() を呼び出す場合は異なります。次に、呼び出し元はシャドウ メソッドがあることを認識し、RectangularDrawingObject のメソッドの代わりにこれを使用します。

RectangularDrawingObject のメソッドシャドウイング メソッドです。では、この一節は何を意味するのでしょうか。

そして、私があなたの主張を正しく理解していれば、これまでに機能したり必要とされPrivate Shadowsたりする可能性のある状況はありません. はい?PrivateVS は、他の多くのキーワード (および など)の場合と同様に、「'Private' と 'Shadows' を組み合わせることはできません」と警告する必要がありますOverridable

4

1 に答える 1

2

Shadowsメンバーの実装を非表示にし、アクセシビリティ コンテキストで新しい実装を提供します。つまり、外部からRectangularDrawingObject's ToXMLInternal()アクセスする場合でも、あなたの場合は有効です。Rectangle呼び出し元は、シャドウイング メソッドがあることを知りません。なぜ彼は?結局のところ、メソッドは非公開です。

ToXMLInternal()内から呼び出す場合Rectangleは別です。次に、呼び出し元はシャドウ メソッドがあることを認識し、RectangularDrawingObject'sメソッドの代わりにこれを使用します。

問題は、なぜこの動作が必要なのかということです。シャドウイングが良いアイデアである場合はまれにあるかもしれませんが、一般的には、それは設計の誤解です。

基本クラスのパブリック メンバーにサブクラスがアクセスできないようにする方法はありません。それは、オブジェクト指向のパラダイム全体と矛盾します。サブクラスでのみ動作を変更できます。

編集

この単純なクラス階層を考えてみましょう:

Class A
    Public Sub Method()
        Console.WriteLine("From A")
    End Sub
End Class

Class B
    Inherits A

    Private Shadows Sub Method()
        Console.WriteLine("From B")
    End Sub
End Class

さて、次のようにすると:

Sub Main()
    Dim obj As New B()
    obj.Method()
End Sub

次に、出力は「From A」です。クラスBを外側から見ると、シャドウイング メソッドがあることがわかりません。メソッドは非公開です。したがって、クラスから継承された public メソッドAが使用され、"From A" がコンソールに出力されます。

class に別のメソッドを追加するとB:

Public Sub CallMethod()
    Method()
End Sub

そしてMain()

obj.CallMethod()

次にCallMethod()、クラス内Bにあり、すぐに使用するプライベート シャドウイング メソッドを確認できます。結果の出力は「From B」です。

CallMethodから継承された(シャドウされていない)メソッドにアクセスすることもできます

MyBase.Method()

「From A」を出力します。

基本クラスのすべての public メソッドは、サブクラスでも使用できることに注意してください。せいぜいこのメソッドを別のパブリック メソッドでシャドウできますが、メソッドを完全に非表示にする方法はありません。Shadowsisに相当する C#はnew、動作を非常によく説明しています。元の実装は保持され、新しい実装がクラスに追加されます。

最後の例が示すように、Private Shadows. ただし、これがどれほど合理的であるかは議論の余地があります。

編集 2

との違いについてのもう 1 つの考えOverrides

上記の例のシャドーイング メソッドが public である場合、

Dim obj As New B()
obj.Method()

「From B」を出力します。もちろん。しかし、次のように呼び出すobjA:

Dim obj As A = New B()
obj.Method()

出力は「From A」です。これは、シャドウされたメソッドがまだそこにあり、 をobj介しAてアクセスすることで、元のメソッドにアクセスするためです。Overridesはメソッドを完全に置き換え、上記の例でも「From B」を出力します。これは、元のメソッドが に存在しなくなったためobjです。

于 2013-09-25T08:23:15.800 に答える