Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么要使用虚拟&x2B;重写是否可以更改派生方法而不使用这些方法?_C#_Inheritance_Methods_Overriding_Virtual - Fatal编程技术网

C# 为什么要使用虚拟&x2B;重写是否可以更改派生方法而不使用这些方法?

C# 为什么要使用虚拟&x2B;重写是否可以更改派生方法而不使用这些方法?,c#,inheritance,methods,overriding,virtual,C#,Inheritance,Methods,Overriding,Virtual,我知道这个问题已经被问了很多次,但我仍然找不到一个直接的答案。 如果我可以在没有这些关键字的情况下更改派生方法,为什么要在派生类中使用带有virtual关键字的方法,然后使用override关键字呢 class Program { static void Main(string[] args) { Furniture furn = new Furniture(); furn.SayWhoYouAre(); Table tab =

我知道这个问题已经被问了很多次,但我仍然找不到一个直接的答案。 如果我可以在没有这些关键字的情况下更改派生方法,为什么要在派生类中使用带有virtual关键字的方法,然后使用override关键字呢

class Program
{
    static void Main(string[] args)
    {
        Furniture furn = new Furniture();
        furn.SayWhoYouAre();

        Table tab = new Table();
        tab.SayWhoYouAre();

        Console.ReadKey();
    }
}

public class Furniture
{
    public Furniture()
    {

    }

    public void SayWhoYouAre()
    {
        Console.WriteLine("I'm Furniture");
    }
}

public class Table: Furniture
{
    public Table()
    {

    }

    public void SayWhoYouAre()
    {
        Console.WriteLine("I'm Table");
    }
}
上述代码写入屏幕:

I'm Furniture
I'm Table

很明显,table对象是一个table和一个Furniture(因此多态性正在发生),并且
SayWhoYouAre()
方法在派生类中被重写。当我在表中时,您将得到输出。如果将override关键字与方法一起使用。否则,它将始终调用基类方法并给出输出I'm Furniture。它被称为运行时多态性

Furniture furn = new Table();        
furn.SayWhoYouAre();

注意:如果未声明非多态性的基类方法
virtual

,则不能在派生类中使用
重写
。您的第二个变量需要声明为派生的
,以使用其
ShowWhoYouAre()
方法。如果您想对整个家具集合调用该方法,并让每个集合使用其特定的实现,会发生什么

var furnitureList = new List<Furniture>();

运行此<代码>家具furn=新桌子();furn.说你是谁和seeso多态性正在发生不,不是你只是调用
家具。说whoyouare()
然后再调用
表。说whoyouare()
没有涉及多态性你不是在重写方法,而是在替换它。查看intellisense,您将看到一条警告,上面写着
SayWhoYouAre隐藏继承的成员家具。SayWhoYouAre
。如果是这样,您应该在
类中将方法更改为
public new void saywho
。文档对@imsmn进行了非常全面的概述。值得一提的是,向方法添加
new
只会抑制编译器警告。行为仍然相同(即,如果
声明为
家具
对象,则仍将调用
家具.SayWhoYouAre()
)。同意,但如果我实例化
家具furn=new Table()和Furniture的
SayWhoYouAre()
为空运行时不知何故知道它现在应该调用表的方法。当家具的方法中也有一些代码时,为什么它不能这样做呢?@Val不,不是这样的。它仅取决于
虚拟
覆盖
新建
关键字。与空方法或空方法无关definition@Val这不是它的工作原理。检查你提出的情况
Furniture.sayWhouare()
为空,因此两个对象都没有输出,因为它们都声明为
Furniture
。但我已经尝试运行代码。实例化
Furniture furn=newtable()后并调用SayWhoYouAre()我确实从表中收到一条消息。但前提是家具中的方法是空的。如果不是,则执行家具中的代码。
class Program
{
    static void Main(string[] args)
    {
        var furnitureList = new List<Furniture>
        {
            new Table(),
            new Furniture()
        };

        foreach (var item in furnitureList)
        {
            item.ShowWhoYouAre();
        }
    }
}

public class Furniture
{
    public virtual void SayWhoYouAre()
    {
        Console.WriteLine("I'm Furniture");
    }
}

public class Table: Furniture
{
    public override void SayWhoYouAre()
    {
        Console.WriteLine("I'm Table");
    }
}