В чем разница между переопределением и новыми ключевыми словами в C #? - PullRequest
67 голосов
/ 05 июля 2011

В чем разница между ключевыми словами override и new в C # при определении методов в иерархиях классов?

Ответы [ 5 ]

83 голосов
/ 05 июля 2011

На следующей странице ваш вопрос очень хорошо обобщен.

Зная, когда использовать переопределение и новые ключевые слова

Резюме

Переопределение : когда метод базового класса переопределяется в производном классе, используется версия в производном классе, даже если вызывающий код не «знает», что объект был экземпляромпроизводный класс.

New : если вы используете ключевое слово new вместо переопределения, метод в производном классе не переопределяет метод в базовом классе, он просто скрывает его.

Если вы не укажете ни новое, ни переопределение, результирующий вывод будет таким же, как если бы вы указали новый, но вы также получите предупреждение компилятора (поскольку вы можете не знать, что скрываетеметод в методе базового класса, или, возможно, вы захотели переопределить его и просто забыли включить ключевое слово).

Переопределение : используется с методом виртуального / абстрактного / переопределения метода в базовом классе

Новое : когда базовый класс не объявил метод как виртуальный/ абстрактные / переопределение

65 голосов
/ 05 июля 2011

new будет затенять метод совершенно новым методом (который может иметь или не иметь одну и ту же сигнатуру) вместо его переопределения (в этом случае новый метод должен иметь одинаковую сигнатуру), что означает, что полиморфизм не будетРабота.Например, у вас есть эти классы:

class A {
    public virtual int Hello() {
        return 1;
    }
}

class B : A {
    new public int Hello(object newParam) {
        return 2;
    }
}

class C : A {
    public override int Hello() {
        return 3;
    }
}

Если вы сделаете это:

A objectA;
B objectB = new B();
C objectC = new C();

Console.WriteLine(objectB.Hello(null)); // 2
Console.WriteLine(objectC.Hello()); // 3

objectA = objectB;

Console.WriteLine(objectA.Hello()); // 1

objectA = objectC;

Console.WriteLine(objectA.Hello()); // 3

Поскольку вы можете определять сигнатуры новых методов с помощью new, компилятору будет невозможно узнатьчто экземпляр A на самом деле является экземпляром B, и новый метод, определяемый B, должен быть доступен.new может использоваться, когда метод, свойство, поле или событие родительского объекта не объявлено с virtual, и из-за отсутствия virtual компилятор не будет «искать» унаследованный метод.Однако с virtual и override это работает.

Я настоятельно рекомендую вам избегать new;в лучшем случае это сбивает с толку, потому что вы определяете метод с именем, которое можно было бы распознать как что-то другое, а в худшем случае он может скрывать ошибки, вносить кажущиеся невозможными ошибки и затруднять расширение функциональности.

9 голосов
/ 08 апреля 2012

Похоже на старый вопрос, позвольте мне попробовать другой ответ:

  1. new: как следует из названия, это новый член в иерархии семейства наследования, который будет использоваться в качестве базового для дальнейшего продвижения по цепочке (если он помечен как виртуальный).

  2. override: Это означает, что я не принимаю реализацию члена моего родительского класса, и я поступлю иначе.

2 голосов
/ 08 февраля 2018

Рассмотрим следующую иерархию классов:

using System;

namespace ConsoleApp
{     
     public static class Program
     {   
          public static void Main(string[] args)
          {    
               Overrider overrider = new Overrider();
               Base base1 = overrider;
               overrider.Foo();
               base1.Foo();

               Hider hider = new Hider();
               Base base2 = hider;
               hider.Foo();
               base2.Foo();
          }   
     }   

     public class Base
     {
         public virtual void Foo()
         {
             Console.WriteLine("Base      => Foo");
         }
     }

     public class Overrider : Base
     {
         public override void Foo()
         {
             Console.WriteLine("Overrider => Foo");
         }
     }

     public class Hider : Base
     {
         public new void Foo()
         {
             Console.WriteLine("Hider     => Foo");
         }
     }
}    

Вывод вышеуказанных кодов должен быть:

Overrider => Foo
Overrider => Foo

Hider     => Foo
Base      => Foo
  • Подкласс overrides виртуальный метод с применением override modifier:
  • Если вы хотите hide член сознательно, в этом случае вы можете применить new modifier к члену в подклассе. The new modifier does nothing more than suppress the compiler warning that would otherwise result
1 голос
/ 05 июля 2011

override позволяет переопределить виртуальный метод в базовом классе, чтобы можно было добавить другую реализацию. new скроет не виртуальный метод в базовом классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...