继承和新关键字

时间:2014-02-03 18:07:47

标签: c# .net inheritance override new-operator

当我添加新关键字或删除时,事情的行为方式相同! 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关键字它可以使用它或不使用它。

4 个答案:

答案 0 :(得分:4)

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

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

BaseClass bcdc = new DerivedClass();

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

同样,使用new访问修饰符不会改变功能,它只为查看类实现的人提供线索,以了解该方法假设隐藏基础实施

答案 1 :(得分:4)

在某些方面,newvirtual/override是相反的关键字。

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

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

答案 2 :(得分:2)

嗯,这正是virtual/overridenew之间的区别!

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

答案 3 :(得分:0)

查看C# Language Specification,第56页:

  

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

当您将变量声明为特定类型时,使用该类型的声明空间完成成员查找,但覆盖成员除外。由于您没有覆盖Method1成员,因此会发现并使用“基类”成员。