想知道以下两者之间的区别:

案例1:基类

public void DoIt();

案例1:继承类

public new void DoIt();

案例2:基类

public virtual void DoIt();

案例2:继承类

public override void DoIt();

根据我运行的测试,情况1和2似乎具有相同的效果。有区别吗,或者有更好的方式吗?


当前回答

这些测试不会显示功能差异:

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()。

其他回答

请尝试以下操作:(case1)

((BaseClass)(new InheritedClass())).DoIt()

编辑:virtual+override在运行时被解析(因此override真正覆盖虚拟方法),而new只是创建同名的新方法,并隐藏旧方法,它在编译时被解析->你的编译器将调用它'看到'的方法

在第一种情况下,您将定义隐藏在父类中。这意味着只有在将对象作为子类处理时才会调用它。如果将类强制转换为其父类型,则将调用父类的方法。在第二个实例中,该方法将被重写,并将被调用,而不管对象是转换为子类还是父类。

在情况1中,如果您使用调用继承类的DoIt()方法,而类型被声明为基类,您甚至可以看到基类的操作。

/* Results
Class1
Base1
Class2
Class2
*/
public abstract class Base1
{
    public void DoIt() { Console.WriteLine("Base1"); }
}
public  class Class1 : Base1 
{
    public new void DoIt() { Console.WriteLine("Class1"); }
}
public abstract class Base2
{
    public virtual void DoIt() { Console.WriteLine("Base2"); }
}
public class Class2 : Base2
{
    public override void DoIt() { Console.WriteLine("Class2"); }
}
static void Main(string[] args)
{
    var c1 = new Class1();
    c1.DoIt();
    ((Base1)c1).DoIt();

    var c2 = new Class2();
    c2.DoIt();
    ((Base2)c2).DoIt();
    Console.Read();
}

我也有同样的问题,真的很困惑, 您应该考虑重写和new关键字只适用于类型为基类的对象和派生类的值的对象。在这种情况下,只有你会看到override和new的效果: 如果你有类A和类B, B继承自类A,然后你像这样实例化一个对象:

A a = new B();

现在,调用方法将考虑它的状态。 Override:意味着它扩展了方法的函数,然后在派生类中使用该方法,而new告诉编译器将该方法隐藏在派生类中,而在基类中使用该方法。 下面是关于这个主题的一个很好的观点:

https://msdn.microsoft.com/EN-US/library/ms173153%28v=VS.140,d=hv.2%29.aspx?f=255&MSPPError=-2147217396

Virtual:表示该方法可以被继承者覆盖

Override:覆盖基类中虚方法的功能,提供不同的功能。

New:隐藏原来的方法(不一定是虚拟的),提供不同的功能。这应该只在绝对必要的情况下使用。

当您隐藏一个方法时,您仍然可以通过向上强制转换为基类来访问原始方法。这在某些情况下很有用,但也很危险。