5

考虑这段代码:

internal class Program
   {

      private static void Main(string[] args)
         {
            var student = new Student();
            student.ShowInfo(); //output --> "I am Student"
        }
    }
    public class Person
    {
        public void ShowInfo()
        {
            Console.WriteLine("I am person");
        }
    }

    public class Student : Person
    {
        public void ShowInfo()
        {
            Console.WriteLine("I am Student");
        }
    }

在上面的代码中,我们不使用方法隐藏。

当创建学生实例并调用showinfo方法时,我的输出是I am Student我不使用new关键字。

为什么不使用方法隐藏时不调用父方法?

4

8 回答 8

13

无论您是否使用new关键字,基本方法都不是虚拟的。所以它总是会被调用的派生方法。唯一的区别是编译器会向您发出警告,因为基本方法是隐藏的并且您没有显式使用new关键字:

“Student.ShowInfo()”隐藏了继承的成员“Person.ShowInfo()”。如果打算隐藏,请使用 new 关键字。

C# 编译器发出此消息是为了警告您,您可能在没有意识到的情况下错误地这样做了。

为了修复警告,如果这种隐藏是故意的,您应该使用 new 关键字:

public new void ShowInfo()
{
    Console.WriteLine("I am Student");
}

如果没有,您应该将基本方法设为虚拟:

public class Person
{
    public virtual void ShowInfo()
    {
        Console.WriteLine("I am person");
    }
}

然后在派生类中覆盖它:

public class Student : Person
{
    public override void ShowInfo()
    {
        Console.WriteLine("I am Student");
    }
}

显然,在这两种情况下,如果需要,您都可以调用基本方法:

public override void ShowInfo()
{
    base.ShowInfo();
    Console.WriteLine("I am Student");
}
于 2013-07-27T12:53:15.973 回答
3

实际上,从程序逻辑的角度来看,new 修饰符根本没有任何作用

新修饰符的唯一作用是记录您的意图,以便:

  • 编译器可以在适当的时候警告你(例如在不隐藏继承成员的声明中使用 new 修饰符时 - 或者相反,即使声明确实隐藏了继承成员也不使用 new 修饰符)

  • 其他开发人员更容易理解您的代码

隐藏/不隐藏真正重要的是您是否使用override 修饰符(只有在继承的成员是虚拟的情况下才能使用)。如果不使用 override 修饰符,则继承的成员始终是隐藏的。在您的示例中,您不使用 override 修饰符,因此您确实隐藏了继承的成员。

注意:不要将“新修饰符”与“新运算符”或“新约束”混淆

于 2013-07-27T13:22:45.877 回答
2

它正在使用方法隐藏,它只是隐式使用。new关键字应该用于明确表明您知道您正在隐藏该方法,但是,您的代码仍将编译并隐藏该方法。虽然这绝对不推荐。

于 2013-07-27T12:52:13.733 回答
1

Student.ShowInfo()隐藏继承的成员Person.ShowInfo()

你最好检查编译器警告

“ConsoleApplication5.Program.Student.ShowInfo()”隐藏了继承的成员“ConsoleApplication5.Program.Person.ShowInfo()”。如果打算隐藏,请使用 new 关键字。

于 2013-07-27T12:53:02.610 回答
1

使用相同的方法签名ShowInfo意味着您将隐藏父类方法。new关键字不是必需的,它只是让开发人员知道当前方法在父类中隐藏了另一个方法。

于 2013-07-27T12:53:14.870 回答
1

这是隐藏,这就是为什么您会收到警告说如果您有意隐藏它,则应该使用new关键字。检查C# Language Spec3.7.1.2的部分。 Hiding through inheritance

当类或结构重新声明从基类继承的名称时,会发生通过继承隐藏名称。这种类型的名称隐藏采用以下形式之一:

• 在类或结构中引入的常量、字段、属性、事件或类型隐藏了所有具有相同名称的基类成员。

• 在类或结构中引入的方法隐藏了所有具有相同名称的非方法基类成员,以及具有相同签名(方法名称和参数计数、修饰符和类型)的所有基类方法。

• 在类或结构中引入的索引器隐藏了具有相同签名(参数计数和类型)的所有基类索引器。

于 2013-07-27T12:53:37.123 回答
1

原因是,当您重新声明基类方法时,它是隐藏的。它被称为通过继承隐藏

于 2013-07-27T12:55:57.740 回答
1

正如其他人所说method hiding is implicit,您是否使用了new关键字。您可以检查这段代码 -

     private static void Main(string[] args)
     {
        Person student = new Student();
        student.ShowInfo(); //output --> "I am person"
     }

当你instantiate base class object with derived class,你的derived method won't get called

于 2013-07-27T13:36:49.990 回答