C# “new” keyword
这是MicoSoft对new关键字的定义:"警告说派生类中的method2方法隐藏了基类中的method2方法。"(https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords)
我似乎无法理解为什么它被定义为"隐藏基类的实现"。如果它实际上"隐藏"了基类的实现,为什么它使用基类的实现而不是派生类的实现?在我看来,"hide"一词的使用与它实际的工作方式相矛盾,而且这种解释倾向于关键字override实际正在做什么;使用派生类的实现而不是基类的实现。
如果有任何答案可以通过使用new关键字消除我对这个"基类实现隐藏"的困惑,我将不胜感激。谢谢大家!
- "我明白它是怎么工作的。"对不起,但显然你不明白。new创建一个与隐藏成员完全相同的名称的成员。但是,您可以&180;t访问隐藏成员,除非您将该实例强制转换为基类。实际上,您有两个成员具有完全相同的名称,因此您必须以某种方式指示要使用哪个成员。
- 好吧,我很抱歉我声称我理解这个概念。我的困惑似乎是base=derived,base有virtual foo(),derived有new foo()。如果关键字"new"隐藏base的foo(),为什么base.foo()使用base的foo()。
- 它将子类实现隐藏在基中,因此基不知道abou Foo由派生实现
Why does it use base class' implementation instead of derived class' implementation
当对基类变量调用"new"时,它将调用基类的实现。当调用派生类变量时,它将调用派生类的实现。
1 2 3 4 5
| Derived d = new Derived ();
Base b = d ;
d .Foo(); //<- Derived's implementation
b .Foo(); //<- Base's implementation |
在这两种情况下,都使用"override"调用派生类的实现。
1 2 3 4 5
| Derived d = new Derived ();
Base b = d ;
d .Foo(); //<- Derived's implementation
b .Foo(); //<- Derived's implementation |
- 是的,我理解使用"new",它将调用基类的实现而不是派生的。但是为什么它被称为"隐藏"了"基类"的实现呢?这个定义让我想到,因为b的foo()是隐藏的,"base b=d;b.foo();"会调用d的foo(),而不是b的foo(),这类似于关键字"override"实际执行的操作。
- 这是比喻语言。"隐藏"在"意义上的"放在前面",而不是"替换"。
- 啊,"摆在前面"似乎是我要找的答案。只是澄清一下,假设"hidden"意味着d的foo()的关键字"new"将b的foo()放在d的foo()前面,这是正确的吗?所以,如果基b=d,调用b.foo()将运行b的foo(),即使d也有foo()的实现,因为b的foo()放在d的foo()前面?
- @我相信你的结论是正确的,但逻辑是错误的。d在b前面。当你有一个b参考时,你会经过d。
- 那么,这次我是否认为b.foo()将运行b的foo()而不是d的foo(),因为变量的类型是b,并且d的foo()被认为是一个新的和完全无关的函数,而不是b的foo(),因为"new"关键字?
- @97尼科当然,这是合理的。
我会这样想:
当Derived隐藏基类Base的成员,并且通过Derived访问时,调用Derived是因为它隐藏Base的实现。但是,当通过Base时,没有任何东西可以隐藏它,因此使用Base的实现。
但是,对于virtual/override的(多态性)方法,Base的方法实际上是被重写的,而不是隐藏的,因此即使通过Base引用访问,它也将使用Derived的方法。
还有(可能是真正的原因):命名事物很难。程序员和其他人一样不擅长它。
- 这就是我的想法,"A之所以被称为是因为它隐藏了B的实现"。但是,根据微软的定义,"new"关键字隐藏了基类实现,在本例中,它会将您的语句重新表述为"a's is called because it hidden a's implementation"。
- @97nico在我的例子中,A是派生类。此外,a不能隐藏自己的实现。不知道你的评论是什么意思
- 如果我的评论使你感到困惑,我深表歉意。我搞不清楚A或B是哪个是基础班和脱轨班。如果a(derrived class)函数()声明为"new",b(base class)函数()声明为"virtual",那么调用a.function()将运行b的函数(),对吗?
- @97NICO号virtual只是意味着它可以被推翻。new仍将进行标准方法隐藏。
- 我真的很抱歉,我很难清晰地表达我的想法。如果b base=derived;base.function()将运行b的函数,对吗?
- @97NICO是,因为派生类中没有重写