为什么我们不调用父方法';不要使用隐藏方法

本文关键字:方法 隐藏 我们 调用 为什么 | 更新日期: 2023-09-27 18:25:13

考虑以下代码:

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");
        }
    }

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

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

当我们不使用方法隐藏时,为什么不调用父方法?

为什么我们不调用父方法';不要使用隐藏方法

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

"Student.ShowInfo()"隐藏继承的成员"Person.ShowInformation()"。如果要隐藏,请使用new关键字。

C#编译器发出这个警告是为了警告你,你可能在没有意识到的情况下犯了错误

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

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");
}

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

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

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

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

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

注意:不要将"new修饰符"与"new运算符"或"new constraint"混淆

它使用的是方法隐藏,它只是隐式使用的。new关键字应用于显式地显示您知道您正在隐藏该方法,但是,您的代码仍将编译并隐藏该方法。尽管这绝对不是建议的。

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

你最好检查编译器警告

"ConsoleApplication5.Program.Student.ShowInfo()"隐藏继承的成员"ConsoleApplication5.Program.Person.ShowInfo()"。使用新的关键字(如果有意隐藏)。

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

它是隐藏的,这就是为什么你会收到一条警告,说如果你有意隐藏它,你应该使用new关键字。检查C#语言规范Hiding through inheritance3.7.1.2部分。

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

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

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

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

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

正如其他人所说的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