繁体   English   中英

VB.NET中的“私人阴影”如何工作

[英]How does “Private Shadows” work in VB.NET

我有3个这样的类的层次结构:

`DrawingObject` > `RectangularDrawingObject` > `Rectangle`

DrawingObject具有以下成员:

Protected Overridable Function ToXMLInternal(type As Type) As String

我只想将此功能公开到第二级(即RectangularDrawingObject ),并从第三级的类( Rectangle等)中隐藏它,所以我在RectangularDrawingObject对其进行了阴影处理:

Private Shadows Function ToXMLInternal(type As Type) As String

在这里考虑Private 由于我已经进行了阴影处理,因此第三级类将不再可以访问基本版本。 并且由于它是私有的,因此该版本也不应被访问。 但是我可以在Rectangle类中访问它(第一级版本)。 为什么会这样? 解决方法是什么?

编辑:

关于Nico的答案:

从外部访问Rectangle时,RectangularDrawingObject的ToXMLInternal()仍然有效。

这是不正确的。 从外部访问Rectangle时,ToXMLInternal()不可用/不应该使用,因为它最好是受保护的。

如果从Rectangle内部调用ToXMLInternal(),则有所不同。 然后,调用者知道存在一个阴影方法,并使用它而不是RectangularDrawingObject的方法。

RectangularDrawingObject的方法阴影方法。 那么这段话是什么意思呢?

而且,如果我正确理解了您的观点,那么就不会有任何可能的情况或需要“ Private Shadows情况。 是? 然后VS应该警告它说“'Private'和'Shadows'不能组合”,就像其他许多关键字(例如PrivateOverridable )一样。

Shadows隐藏了成员的实现,并在其可访问性上下文中提供了一个新成员。 这意味着在您的情况下,从外部访问Rectangle时, RectangularDrawingObject's ToXMLInternal()仍然有效。 调用者只是不知道有一个隐藏方法。 他怎么会 毕竟该方法是私有的。

如果从Rectangle内部调用ToXMLInternal() ,则有所不同。 然后,调用者知道存在一个阴影方法,并使用它而不是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类,因此看不到有任何阴影方法。 该方法是私有的。 因此,将使用从类A继承的公共方法,并将“从A”打印到控制台。

如果我们向类B添加另一个方法:

Public Sub CallMethod()
    Method()
End Sub

和在Main()

obj.CallMethod()

然后CallMethod()在类B并且可以看到它立即使用的私有阴影方法。 结果输出为“来自B”。

您甚至可以使用以下方法访问CallMethod的继承的(无阴影)方法:

MyBase.Method()

这将输出“来自A”。

请记住,基类的每个公共方法也可用于子类。 您最多可以将这个方法与另一个公共方法一起使用,但是无法完全隐藏该方法。 相当于Shadows的C#是new ,它也很好地描述了该行为。 保留原始实现,并将新实现添加到该类。

如最后一个示例所示,在某些情况下可能会使用“ Private Shadows 虽然,这可能有多合理,这是有争议的。

编辑2

关于“ Overrides的区别的另一个思考。

如果上面示例中的阴影方法是公开的,则

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

将输出“来自B”。 当然。 但是,如果我们将obj称为A

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

那么输出是“ From A”。 这是因为阴影方法仍然存在,并且通过A访问obj可以访问原始方法。 Overrides将完全替代该方法,甚至上面的示例也将输出“ From B”,因为obj中不再存在原始方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM