c#:调用继承的基本方法时的控制流,其中inturn调用在派生类中设置为new的基本虚方法

时间:2017-12-25 06:29:28

标签: c# inheritance

免责声明:我对这个编码世界完全是新手! 在我学习c#的课程中,我读了这篇文章。 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords

代码:

public class Car
{
    public void DescribeCar()
    {
        Console.WriteLine("Car: Four wheels and an engine.");
        ShowDetails();
    }

    public virtual void ShowDetails()
    {
        Console.WriteLine("Car: Standard transportation.");
    }
}

public class ConvertibleCar : Car
{
    public new void ShowDetails()
    {
        Console.WriteLine("ConvertibleCar: A roof that opens up.");
    }
}

ConvertibleCar myCC = new ConvertibleCar();
myCC.DescribeCar();
myCC.ShowDetails();

//Output
Car: Four wheels and an engine.
Car: Standard transportation.
ConvertibleCar: A roof that opens

问题:我希望凭借我的理解,我应该得到" ConvertibleCar:一个屋顶而不是打开"在我的第二和第三行输出中。 在派生类上直接调用ShowDetails时,以及在基类中的方法中,它有什么不同。 PS:派生类中的showdetials设置为new。

3 个答案:

答案 0 :(得分:0)

因为new你有效地隐藏了ShowDetails(实际上,在VB.NET中有Shadows个关键字。此外,使用new,您可以将ShadowDetails设为属性!

让我们创建两个类:Base和Derived:

class Base
{
    public virtual int GetInt()
    {
        return 10;
    }
}

class Derived : Base
{
    public new int GetInt()
    {
        return 11;
    }
}

现在,让我们测试一下:

Base b;
Derived d;
int x;

b = new Derived();
d = new Derived();

x = b.GetInt(); // x = 10 [Base.GetInt()]
x = d.GetInt(); // x = 11 [Derived.GetInt()]

如您所见,虽然已为b分配了派生,但它仍指向Base

但是,让我们做一些完全不同的事情 - 让方法变成财产!

class Derived : Base
{
    public new int GetInt
    {
        get { return 11; }
    }
}

现在,当我们运行上一个测试代码时,我们会看到x = 10

x = d.GetInt(); // x = 10

但是,等等,我们在GetInt()课程中没有Derived方法!为什么编译代码?这很简单 - 因为我们使用GetInt属性隐藏了GetInt()方法,现在从GetInt()调用了Base!为了使事情更加混乱,IntelliSense不会在GetInt()变量上显示d方法,但编译器会满意。要获得11,您需要致电财产:

x = d.GetInt;

您还可以将GetInt()方法转换为委托:

class Derived : Base
{
    public new delegate int GetInt();
}

并使用它:

Derived.GetInt getIntDelegate = () => 12;
Console.WriteLine(getIntDelegate()); // Prints 12

答案 1 :(得分:0)

用于隐藏基础成员/方法的new关键字。所以

public new void ShowDetails()
{
    Console.WriteLine("ConvertibleCar: A roof that opens up.");
}

ShowDetails方法是new类的ConvertibleCar方法,基类ShowDetails方法完全不同,并且不在固有链中。想象一下,您可以在ShowDetails2类中定义类似ConvertibleCar的方法名称。情况也是如此。

此外,如果您使用覆盖keyword而不是newConvertibleCar类将覆盖ShowDetails方法。

public class ConvertibleCar : Car
{
    public override void ShowDetails()
    {
        Console.WriteLine("ConvertibleCar: A roof that opens up.");
    }
}

输出将是;

Car: Four wheels and an engine.
ConvertibleCar: A roof that opens.
ConvertibleCar: A roof that opens.

答案 2 :(得分:0)

要获得预期的输出,请使用new代替public override void ShowDetails() { Console.WriteLine("ConvertibleCar: A roof that opens up."); }

new

如果您使用ShowDetails,则阴影基类中的override方法。这意味着只有在从派生类变量调用方法时才会使用派生类实现。

ShowDetails做了不同的事情。如果覆盖public void DescribeCar() { Console.WriteLine("Car: Four wheels and an engine."); ShowDetails(); <-------- } ,则只要对象的基础类型是派生类,无论变量的类型如何,都将始终使用派生类实现。

这解释了为什么第二行输出不同。第二行是从这一行产生的:

ShowDetails

this.ShowDetails表示thisCar的类型为ConvertibleCar,但实际上是指ShowDetails的对象。由于Car被遮蔽,因此会调用this的实现(因为Car的类型为name!)