1

我有这样的 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。由于我已经遮蔽了,因此 3 级课程应该不再可以访问基本版本。而且由于它是私有的,所以这个版本也不应该被访问。但我可以在Rectangle课堂上访问它(第一级版本)。为什么呢?解决方法是什么?

编辑:

关于尼科的回答:

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

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

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

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

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

4

1 回答 1

2

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

如果你ToXMLInternal()从里面打电话Rectangle,那就不一样了。然后调用者知道有一个阴影方法,并使用 this 代替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

然后输出是“来自A”。您B从外部查看类,因此看不到有阴影方法。该方法是私有的。因此,使用从类继承的公共方法,A并将“From A”打印到控制台。

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

Public Sub CallMethod()
    Method()
End Sub

并且在Main()

obj.CallMethod()

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

您甚至可以从CallMethodwith访问继承的(非阴影)方法

MyBase.Method()

这将输出“来自A”。

请记住,基类的每个公共方法也可用于子类。您最多可以用另一个公共方法隐藏此方法,但没有办法完全隐藏该方法。的 C# 等效项Shadowsis new,它也很好地描述了该行为。原始实现被保留,新的实现被添加到类中。

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

编辑 2

只是另一个想法的差异Overrides

如果上例中的遮蔽方法是公开的,那么

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

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

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

那么输出是“来自A”。那是因为阴影方法仍然存在,通过访问objA您可以访问原始方法。Overrides将完全替换该方法,甚至上面的示例也会输出“From B”,因为原始方法不再存在于obj.

于 2013-09-25T08:23:15.800 回答