想知道以下两者之间的区别:
案例1:基类
public void DoIt();
案例1:继承类
public new void DoIt();
案例2:基类
public virtual void DoIt();
案例2:继承类
public override void DoIt();
根据我运行的测试,情况1和2似乎具有相同的效果。有区别吗,或者有更好的方式吗?
想知道以下两者之间的区别:
案例1:基类
public void DoIt();
案例1:继承类
public new void DoIt();
案例2:基类
public virtual void DoIt();
案例2:继承类
public override void DoIt();
根据我运行的测试,情况1和2似乎具有相同的效果。有区别吗,或者有更好的方式吗?
当前回答
这两种情况的区别在于,在情况1中,基本DoIt方法不会被覆盖,只是被隐藏。这意味着变量的类型取决于调用哪个方法。例如:
BaseClass instance1 = new SubClass();
instance1.DoIt(); // Calls base class DoIt method
SubClass instance2 = new SubClass();
instance2.DoIt(); // Calls sub class DoIt method
这确实会令人困惑,并导致非预期的行为,如果可能的话应该避免。所以首选的方法是情形2。
其他回答
none、virtual、override、new和abstract的所有组合:
new:它只是隐藏基类的方法,但如果你想要访问它。
override:它覆盖了基类的方法,即使你想访问它也无法访问。
例子
using System;
public class Program
{
public static void Main()
{
BaseClass test = new DerivedClass();
var result = test.DoSomething();
Console.WriteLine(result);
}
class BaseClass
{
public string DoSomething()
{
return "Base result";
}
}
class DerivedClass : BaseClass
{
public new string DoSomething()
{
return "Derived result";
}
}
}
结果:基础结果
附注:我从下面的链接复制并稍微改变了上面的例子: https://stackoverflow.com/a/45822233/10995103
如果派生类中使用了关键字重写,则其重写父方法。
如果派生类中使用了关键字new,则派生方法被父方法隐藏。
这些测试不会显示功能差异:
BaseClass bc = new BaseClass();
bc.DoIt();
DerivedClass dc = new DerivedClass();
dc.ShowIt();
在这个例子中,被调用的Doit就是您期望被调用的Doit。
为了看到区别,你必须这样做:
BaseClass obj = new DerivedClass();
obj.DoIt();
您将看到,如果您运行该测试,在情况1中(正如您定义的那样),调用BaseClass中的DoIt(),在情况2中(如您定义的那样),调用DerivedClass中的DoIt()。
其中,new是最令人困惑的。通过实验,new关键字就像给开发人员提供了一个选项,通过显式定义类型,用基类实现覆盖继承的类实现。这就像反过来思考一样。
在下例中,结果将返回"Derived result",直到类型显式定义为BaseClass test,才会返回"Base result"。
class Program
{
static void Main(string[] args)
{
var test = new DerivedClass();
var result = test.DoSomething();
}
}
class BaseClass
{
public virtual string DoSomething()
{
return "Base result";
}
}
class DerivedClass : BaseClass
{
public new string DoSomething()
{
return "Derived result";
}
}