vij*_*ter 13 .net c# oop polymorphism inheritance
任何人都可以用一个有效的例子解释隐藏在C#中的方法的实际用法吗?
如果使用new派生类中的关键字定义方法,则无法覆盖该方法.然后它与创建一个具有不同名称的新方法(除了在基类中提到的方法之外)相同.
有没有具体的理由使用new关键字?
jer*_*enh 10
我有时对新关键字使用的一个用法是在并行继承树中使用'穷人的属性协方差'.考虑这个例子:
public interface IDependency
{
}
public interface ConcreteDependency1 : IDependency
{
}
public class Base
{
protected Base(IDependency dependency)
{
MyDependency = dependency;
}
protected IDependency MyDependency {get; private set;}
}
public class Derived1 : Base // Derived1 depends on ConcreteDependency1
{
public Derived1(ConcreteDependency1 dependency) : base(dependency) {}
// the new keyword allows to define a property in the derived class
// that casts the base type to the correct concrete type
private new ConcreteDependency1 MyDependency {get {return (ConcreteDependency1)base.MyDependency;}}
}
Run Code Online (Sandbox Code Playgroud)
继承树Derived1:Base对ConcreteDependency1:IDependency'具有'parallell依赖'.在派生类中,我知道MyDependency的类型为ConcreteDependency1,因此我可以使用new关键字从基类中隐藏属性getter.
编辑:请参阅Eric Lippert撰写的这篇博文,以获得对新关键字的详细解释.
C#不仅支持方法覆盖,还支持方法隐藏.简单地说,如果方法没有覆盖派生方法,它就会隐藏它.必须使用new关键字声明隐藏方法.因此,第二个清单中正确的类定义是:
using System;
namespace Polymorphism
{
class A
{
public void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public new void Foo() { Console.WriteLine("B::Foo()"); }
}
class Test
{
static void Main(string[] args)
{
A a;
B b;
a = new A();
b = new B();
a.Foo(); // output --> "A::Foo()"
b.Foo(); // output --> "B::Foo()"
a = new B();
a.Foo(); // output --> "A::Foo()"
}
}
}
Run Code Online (Sandbox Code Playgroud)
我认为ArsenMkrt的例子并不完全正确,至少它没有完全解释隐藏功能.通过从B类中的Foo方法中删除new关键字,您仍然可以获得输出
A::Foo()
B::Foo()
A::Foo()
Run Code Online (Sandbox Code Playgroud)
在像Java这样的编程语言中,所有方法都是"虚拟的",你希望获得输出
A::Foo()
B::Foo()
B::Foo()
Run Code Online (Sandbox Code Playgroud)
通过上面的ArsenMkrt代码,由于实例化
A a;
B b;
a = new A();
b = new B();
a.Foo();
b.Foo();
a = new B(); //<< Here
a.Foo();
Run Code Online (Sandbox Code Playgroud)
然而,在他的例子中,你仍然得到"A :: Foo()"因为在C#方法中默认不是虚拟的,因此方法B :: Foo()自动隐藏A的Foo().要实现多态行为,必须按如下方式编写它:
class A
{
public virtual void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public override void Foo() { Console.WriteLine("B::Foo()"); }
}
Run Code Online (Sandbox Code Playgroud)
现在是"new"关键字出现的地方.实际上,当你从B :: Foo()离开"覆盖"时,你再次隐藏A :: Foo()意味着你不会覆盖它的默认行为而你不实现多态,即你再次得到"A :: Foo()"作为输出.同样可以实现 - 这里我不会100%理解为什么你要把它放在 - 通过放置"new"关键字,如...
class A
{
public virtual void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public new void Foo() { Console.WriteLine("B::Foo()"); }
}
Run Code Online (Sandbox Code Playgroud)
然后你再次获得输出
A::Foo()
B::Foo()
A::Foo()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10025 次 |
| 最近记录: |