“私有阴影”如何在VB.NET中运行

时间:2013-09-25 04:13:27

标签: .net vb.net oop

我有3个类的层次结构,如下所示:

`DrawingObject` > `RectangularDrawingObject` > `Rectangle`

DrawingObject有以下成员:

Protected Overridable Function ToXMLInternal(type As Type) As String

我想将此函数仅公开到第二级(即RectangularDrawingObject)并将其隐藏在第3级(Rectangle等)的类中,因此我将其隐藏在RectangularDrawingObject中:

Private Shadows Function ToXMLInternal(type As Type) As String

在此处考虑Private。由于我已经隐藏了,因此第3级课程不再可以访问基础版本。由于它是私有的,因此也不应该访问此版本。但是我能够在Rectangle课程中访问它(第一级版本)。为什么会这样?什么是解决方法?

修改

关于Nico的回答:

从外部访问Rectangle时,

RectangularDrawingObject的ToXMLInternal()仍然有效。

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

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

RectangularDrawingObject的方法阴影方法。那段经文到底是什么意思?

如果我理解你的观点,那么Private Shadows就不会有任何工作或被要求的情况。是?然后,VS应警告它说''私有'和'阴影'不能合并“,就像许多其他关键字一样(例如PrivateOverridable)。

1 个答案:

答案 0 :(得分: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,因此看不到有阴影方法。该方法是私有的。因此,使用类A中继承的公共方法,并将“From A”打印到控制台。

如果我们向课程B添加另一种方法:

Public Sub CallMethod()
    Method()
End Sub

并在Main()

obj.CallMethod()

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

您甚至可以使用

CallMethod访问继承(非阴影)方法
MyBase.Method()

将输出“From A”。

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

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

编辑2

关于与Overrides的区别的另一个想法。

如果上例中的阴影方法是公开的,那么

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

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

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

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