Shi*_*iji 179 c# inheritance overriding new-operator
想知道以下几点之间的区别:
案例1:基类
public void DoIt();
Run Code Online (Sandbox Code Playgroud)
案例1:继承的类
public new void DoIt();
Run Code Online (Sandbox Code Playgroud)
案例2:基类
public virtual void DoIt();
Run Code Online (Sandbox Code Playgroud)
案例2:继承的类
public override void DoIt();
Run Code Online (Sandbox Code Playgroud)
根据我运行的测试,情况1和2似乎具有相同的效果.有区别,还是首选方式?
rah*_*hul 246
override修饰符可用于虚方法,必须用于抽象方法.这表明编译器使用方法的最后定义的实现.即使在对基类的引用上调用该方法,它也将使用覆盖它的实现.
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public override void DoIt()
{
}
}
Base b = new Derived();
b.DoIt(); // Calls Derived.DoIt
Run Code Online (Sandbox Code Playgroud)
Derived.DoIt
如果覆盖将会打电话Base.DoIt
.
new修饰符指示编译器使用子类实现而不是父类实现.任何不引用您的类但父类的代码都将使用父类实现.
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public new void DoIt()
{
}
}
Base b = new Derived();
Derived d = new Derived();
b.DoIt(); // Calls Base.DoIt
d.DoIt(); // Calls Derived.DoIt
Run Code Online (Sandbox Code Playgroud)
Base.DoIt
那么先打电话Derived.DoIt
.它们实际上是两个完全独立的方法,它们碰巧具有相同的名称,而不是覆盖基本方法的派生方法.
来源:微软博客
Jon*_*n B 168
virtual:表示继承者可以覆盖方法
override:覆盖基类中虚方法的功能,提供不同的功能.
new:隐藏原始方法(不必是虚拟的),提供不同的功能.这应该只在绝对必要的地方使用.
隐藏方法时,仍然可以通过向上转换为基类来访问原始方法.这在某些情况下很有用,但很危险.
tva*_*son 15
在第一种情况下,您将定义隐藏在父类中.这意味着只有在将对象作为子类处理时才会调用它.如果将类强制转换为其父类型,则将调用父类的方法.在第二个实例中,该方法被重写,并且无论对象是否被强制转换为子类或父类,都将调用该方法.
new
意味着尊重您的 REFERENCE type(left-hand side of=
) ,从而运行引用类型的方法。如果重新定义的方法没有new
关键字,则其行为与其一样。而且,它也被称为非多态继承。也就是说,“我正在派生类中创建一个全新的方法,它与基类中的任何同名方法完全无关。” - 惠特克说override
,必须virtual
在其基类中与关键字一起使用,意味着尊重您的 OBJECT 类型( 的右侧=
),从而无论引用类型如何都运行覆盖的方法。此外,它也被称为多态继承。
我记住这两个关键字的方式是它们彼此相反。
override
:virtual
必须定义关键字以覆盖该方法。使用override
关键字的方法,无论引用类型(基类或派生类的引用)如果用基类实例化,基类的方法都会运行。否则,派生类的方法运行。
new
: 如果关键字被方法使用,与override
关键字不同,引用类型很重要。如果用派生类实例化,引用类型为基类,则运行基类的方法。如果用派生类实例化,引用类型是派生类,则运行派生类的方法。即,它是override
关键字的对比。顺便说一句,如果您忘记或省略向方法添加新关键字,则编译器的行为默认为使用new
关键字。
class A
{
public string Foo()
{
return "A";
}
public virtual string Test()
{
return "base test";
}
}
class B: A
{
public new string Foo()
{
return "B";
}
}
class C: B
{
public string Foo()
{
return "C";
}
public override string Test() {
return "derived test";
}
}
Run Code Online (Sandbox Code Playgroud)
调用主:
A AClass = new B();
Console.WriteLine(AClass.Foo());
B BClass = new B();
Console.WriteLine(BClass.Foo());
B BClassWithC = new C();
Console.WriteLine(BClassWithC.Foo());
Console.WriteLine(AClass.Test());
Console.WriteLine(BClassWithC.Test());
Run Code Online (Sandbox Code Playgroud)
输出:
A
B
B
base test
derived test
Run Code Online (Sandbox Code Playgroud)
新的代码示例,
class X
{
protected internal /*virtual*/ void Method()
{
WriteLine("X");
}
}
class Y : X
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Y");
}
}
class Z : Y
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Z");
}
}
class Programxyz
{
private static void Main(string[] args)
{
X v = new Z();
//Y v = new Z();
//Z v = new Z();
v.Method();
}
Run Code Online (Sandbox Code Playgroud)
尝试以下:(case1)
((BaseClass)(new InheritedClass())).DoIt()
Run Code Online (Sandbox Code Playgroud)
编辑:虚拟+覆盖在运行时被解析(所以覆盖真的覆盖虚方法),而new只是创建具有相同名称的新方法,并隐藏旧的,它在编译时解析 - >你的编译器将调用它的方法'看到
归档时间: |
|
查看次数: |
74436 次 |
最近记录: |