[英]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'不能组合”,就像其他许多关键字(例如Private
和Overridable
)一样。
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
。 虽然,这可能有多合理,这是有争议的。
关于“ 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.