Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# 继承和新关键字_C#_.net_Inheritance_Overriding_New Operator - Fatal编程技术网

C# 继承和新关键字

C# 继承和新关键字,c#,.net,inheritance,overriding,new-operator,C#,.net,Inheritance,Overriding,New Operator,当我添加新关键字或删除关键字时,事情的行为都是一样的!new关键字应该重新实现基类的方法并将其隐藏,以下是示例: class Program { static void Main(string[] args) { BaseClass bc = new BaseClass(); DerivedClass dc = new DerivedClass(); BaseClass bcdc =

当我添加新关键字或删除关键字时,事情的行为都是一样的!new关键字应该重新实现基类的方法并将其隐藏,以下是示例:

class Program
    {
        static void Main(string[] args)
        {
            BaseClass bc = new BaseClass();
            DerivedClass dc = new DerivedClass();
            BaseClass bcdc = new DerivedClass();

            Console.WriteLine("bc __________________");
            bc.Method1();
            bc.Method2();
            Console.WriteLine("dc __________________");
            dc.Method1();
            dc.Method2();
            Console.WriteLine("bcdc __________________");
            bcdc.Method1();
            bcdc.Method2();

            Console.ReadLine();
        }
    }

    class BaseClass
    {
        public void Method1()
        {
            Console.WriteLine("Base - Method1");
        }
        public void Method2()
        {
            Console.WriteLine("Base - Method2");
        }
    }

    class DerivedClass : BaseClass
    {
        public new void Method1()
        {
            Console.WriteLine("Derived - Method1");
        }
        public void Method2()
        {
            Console.WriteLine("Derived - Method2");
        }
    }
bcdc的输出将显示 基本方法1 调用bcdc.Method1()时;它不是应该显示“派生方法1”吗?如果不是,请向我解释原因。(当使用Virtual/override时,它可以很好地工作,我很满意),但是使用new关键字时,它的工作方式与使用它或不使用它类似。

使用将简单地隐藏基本实现,它不会覆盖它。不使用
new
修饰符做同样的事情,但是隐式地

将变量定义为
基类
时,是否将其初始化为派生类并不重要。您仍然只能访问基类中定义的方法

BaseClass bcdc = new DerivedClass();

Console.WriteLine("bcdc __________________");
bcdc.Method1();
bcdc.Method2();
同样,使用
new
access修饰符并不会改变功能,它只为查看类实现的人提供了一个线索,让他们了解该方法应该隐藏基本实现。

使用将只隐藏基本实现,而不会覆盖它。不使用
new
修饰符做同样的事情,但是隐式地

将变量定义为
基类
时,是否将其初始化为派生类并不重要。您仍然只能访问基类中定义的方法

BaseClass bcdc = new DerivedClass();

Console.WriteLine("bcdc __________________");
bcdc.Method1();
bcdc.Method2();

同样,使用
new
access修饰符并不会改变功能,它只为查看类实现的人提供了一个线索,让他们明白该方法应该隐藏基本实现。

好吧,这正是
虚拟/覆盖
新建
之间的区别

  • 在第一种情况下(
    virtual/override
    ),将调用被重写的方法,而不管从哪种类型的变量调用它。这种行为有一个名字,叫做多态性,在面向对象编程中被广泛使用
  • 在第二种情况下(
    new
    ),这取决于!如果变量的类型在定义
    new
    方法之前,则从该变量调用时将调用旧方法。否则,将调用较新的方法。这被称为方法阴影(方法共享相同的名称,但它们实际上不同,而且可能不相关-这就是为什么会有不同的行为),当基类引入了一个新方法,而您的派生类已经有了该方法时,将使用该方法。要告诉C#它们的关系不是虚拟的/重写的,您可以使用
    new
    。这通常是最好避免的

    • 这正是
      虚拟/覆盖
      之间的区别

      • 在第一种情况下(
        virtual/override
        ),将调用被重写的方法,而不管从哪种类型的变量调用它。这种行为有一个名字,叫做多态性,在面向对象编程中被广泛使用
      • 在第二种情况下(
        new
        ),这取决于!如果变量的类型在定义
        new
        方法之前,则从该变量调用时将调用旧方法。否则,将调用较新的方法。这被称为方法阴影(方法共享相同的名称,但它们实际上不同,而且可能不相关-这就是为什么会有不同的行为),当基类引入了一个新方法,而您的派生类已经有了该方法时,将使用该方法。要告诉C#它们的关系不是虚拟的/重写的,您可以使用
        new
        。这通常是最好避免的

      在某些方面,
      new
      virtual/override
      是相反的关键字

      • virtual/override
        :用于跨继承层次结构中的一系列类型声明具有单个实现的单个方法
      • new
        :用于显式地声明一个新方法,与具有相同签名的所有其他方法分开。没有
        new
        也有同样的效果,只是隐式的

      在这种情况下,代码没有
      virtual
      方法,因此编译器静态绑定到由调用它的引用类型指定的方法

      ,在某些方面
      new
      virtual/override
      是相反的关键字

      • virtual/override
        :用于跨继承层次结构中的一系列类型声明具有单个实现的单个方法
      • new
        :用于显式地声明一个新方法,与具有相同签名的所有其他方法分开。没有
        new
        也有同样的效果,只是隐式的
      在这种情况下,代码没有
      虚拟
      方法,因此编译器静态绑定到由调用它的引用类型指定的方法

      请查看,第56页:

      声明在声明所属的声明空间中定义名称。除了重载成员(§3.6)之外,在声明空间中有两个或多个引入同名成员的声明是编译时错误

      当您将变量声明为特定类型时,成员查找将使用该类型的声明空间完成,被重写的成员除外。由于您尚未重写
      方法1
      成员,因此会发现并使用基类的成员。

      请查看,第56页:

      声明在声明所属的声明空间中定义名称。除了重载成员(§3.6)之外,如果有两个或多个声明在声明中引入具有相同名称的成员,则是编译时错误