在C ++中,它使用“using”和C#?
完成public class foo
{
public void print(string s) {...}
}
public class bar : foo
{
// shadowing
public void print(object o) {...}
}
如何宣传foo.print
,因此foo.print
和bar.print
与编译器处于同一“级别”(当然为bar
)?
最初我添加了一个关于阴影和覆盖之间常见混淆的段落,但之后我将其删除了,因为我认为这会让读者反感。
阴影就像跨越继承树的重载一样。阴影 NOT 覆盖。
在解析重载方法foo.print
时,不再考虑投影print
。推广foo.print
会使其恢复正常 - 因此,当我致电bar_object.print("hello")
时,系统会调用方法foo.print
。
答案 0 :(得分:3)
在您的具体示例中,bar.print(object)
确实“遮蔽”了更具体的foo.print(string)
:
new bar().print("i am a string");
这会调用bar
上定义的方法,尽管foo
上的方法会有一个更好地匹配类型的参数。
这里发生的事情如下:编译器在bar
上找到一个具有正确名称(“print”)的方法,正确数量的参数(1)以及传入参数可转换为的参数类型( string
可以转换为object
)
因此,编译器没有理由进一步查看继承链。
据我所知,没有类似于C ++ using
的构造
如果要使用基类上定义的方法,基本上有三个选项:
在来电方:将bar
实例转换为foo
:
var bar = new bar();
var foo = (foo)bar;
foo.print("i am a string"); // Will call foo.print(string)
在calee方面:在bar.print(object)
内检查传递参数的类型:
public void print(object o)
{
var s = o as string;
if(s != null)
base.print(s);
else
{
// Other code.
}
}
这将最接近C ++ using
:实际上覆盖或隐藏派生类中的原始方法:
public class bar : foo
{
public new void print(string s)
{
base.print(s);
}
public void print(object o)
{
// some code
}
}