1

我有以下代码:

class Visitor 
{
    internal virtual void Visit(Node n) { }
}

class VisitorSpecial : Visitor 
{
    internal new void Visit(Node n) { }
}

class Base
{ 
    internal virtual void Accept(Visitor v) { }
    internal virtual void Accept(VisitorSpecial v) { }
}

class Node : Base
{
    internal override void Accept(Visitor v){ v.Visit(this); }
    internal override void Accept(VisitorSpecial v){ v.Visit(this); }
}

调用时是否有任何理由 Accept(Visitor v) 选择该方法 new Node().Accept(new VisitorSpecial())

更新:好的,我的错,我意识到我在访问者中使用“新”而不是覆盖。现在我知道为什么“新突破多态性”了。这使我的问题完全愚蠢。谢谢您的帮助。

4

2 回答 2

4

不知道为什么会选择它(这可能是因为它在类声明中的第一个并且与提供的参数匹配),但是

Accept(VisitorSpecial v)

在这种情况下,函数毫无意义,似乎是对多态性的误解。请尝试以下操作以了解原因:

class Visitor 
{
    internal virtual void Visit(Node n) { Console.WriteLine("In normal visitor"); }
}

class VisitorSpecial : Visitor 
{
    internal override void Visit(Node n) { Console.WriteLine("In special visitor"); }
}

class Base
{ 
    internal virtual void Accept(Visitor v) { }
}

class Node : Base
{
    internal override void Accept(Visitor v){ v.Visit(this); }
}

有了上述,调用

someNode.Accept(new VisitorSpecial());

将产生输出

> In special visitor
于 2009-10-19T10:08:14.080 回答
2

我想您问的是特定语言(C#?)的问题。给定参数,由语言选择最合适的重载(注意:不是覆盖!)。这取决于它使用的函数查找类型:静态(编译时)或动态(运行时)。

如果您的语言使用静态绑定,它可能会选择最具体的调用,在这种情况下,n.Accept( new VisitorSpecial() )将调用第二个重载。然而,

Visitor v = new VisitorSpecial();
n.Accept( v );

将静态绑定到Node::Accept( Visitor )函数。

如果语言使用动态绑定,它可以根据参数的实际运行时类型选择被调用的函数。

一般来说,你可以通过不使用重载来完全解决这个问题,这只是语法糖:区分AcceptVisitorand AcceptSpecialVisitor。添加一个AcceptManagerand AcceptJustSimplyMy

于 2009-10-19T10:25:19.693 回答