Размер шрифта:
Руководство по программированию на C#. Использование ключевых слов Override и New | Microsoft Docs

Руководство по программированию на C#. Использование ключевых слов Override и New | Microsoft Docs

Использование ключевых слов "Override" и "New" (Руководство по программированию в C#)

В C# метод в производном классе может иметь то же имя, что и метод в базовом классе. Можно задать способ взаимодействия методов, воспользовавшись ключевыми словами new и override. Модификатор override override метод virtual базового класса, а модификатор new virtual доступный метод базового класса. Эта разница показана в примере в этой статье.

В консольном приложении объявите два класса — BaseClass и DerivedClass . Тип DerivedClass наследуется от типа BaseClass .

В методе Main объявите переменные bc , dc и bcdc .

Параметр bc имеет тип BaseClass и его значение — тип BaseClass .

Параметр dc имеет тип DerivedClass и его значение — тип DerivedClass .

Параметр bcdc имеет тип BaseClass и его значение — тип DerivedClass . Это переменная, на которую следует обратить внимание.

Поскольку bc и bcdc имеют тип BaseClass , они могут только напрямую обращаться к методу Method1 (если не используется приведение). Переменная dc может обращаться к Method1 и Method2 . Эти связи показаны в следующем коде.

Далее добавьте следующий метод Method2 в класс BaseClass . Сигнатура этого метода соответствует сигнатуре метода Method2 в DerivedClass .

Поскольку BaseClass теперь имеет метод Method2 , можно добавить второй оператор вызова для переменных bc и bcdc класса BaseClass , как показано в следующем коде.

При построении проекта видно, что добавление метода Method2 в BaseClass вызывает предупреждение. Предупреждение говорит, что метод Method2 в DerivedClass скрывает метод Method2 в BaseClass . Рекомендуется использовать ключевое слово new в определении Method2 , если требуется получить такой результат. Другой вариант — переименовать один из методов Method2 для разрешения предупреждения, но это не всегда целесообразно.

Прежде чем добавлять new , запустите программу, чтобы увидеть выходные данные дополнительных операторов вызова. Отобразятся следующие результаты.

Ключевое слово new сохраняет связи, дающие этот результат, однако подавляет предупреждение. Переменные, имеющие тип BaseClass , продолжают обращаться к элементам класса BaseClass , а переменная, имеющая тип DerivedClass , продолжает обращаться к элементам класса DerivedClass в первую очередь, а затем к элементам, унаследованным от BaseClass .

Чтобы подавить предупреждение, добавьте модификатор new в определение Method2 в классе DerivedClass , как показано в следующем коде. Модификатор можно добавить перед или после public .

Запустите программу еще раз, чтобы убедиться, что выходные данные не изменились. Также убедитесь, что предупреждение больше не появляется. Используя ключевое слово new , вы утверждаете, что вам известно, что модифицируемый им член скрывается членом, который наследуется от базового класса. Дополнительные сведения о скрытии имен через наследование см. в разделе Модификатор new.

Чтобы противопоставить это поведение эффекту использования override , добавьте в DerivedClass следующий метод. Модификатор override можно добавить перед или после public .

Добавьте модификатор virtual в определение Method1 в BaseClass . Модификатор virtual можно добавить перед или после public .

Снова запустите проект. Обратите особое внимание на последние две строки следующих выходных данных.

Использование модификатора override позволяет bcdc осуществлять доступ к методу Method1 , который определен в DerivedClass . Как правило, это требуемое поведение в иерархиях наследования. Требуется, чтобы объекты со значениями, созданными из производного класса, использовали определенные в производном классе методы. Это поведение достигается с использованием override для расширения метода базового класса.

Следующий код содержит полный пример.

В следующем примере показано подобное поведение в другом контексте. В примере определяются три класса: базовый класс Car и два класса, производных от него: ConvertibleCar и Minivan . Базовый класс содержит метод DescribeCar . Этот метод отображает общее описание автомобиля, а затем вызывает ShowDetails для предоставления дополнительных сведений. Каждый из трех классов определяет метод ShowDetails . Для определения метода ShowDetails в классе ConvertibleCar используется модификатор new . Для определения метода ShowDetails в классе Minivan используется модификатор override .

В примере проверяется версия вызванного ShowDetails . Следующий метод, TestCars1 , объявляет экземпляр каждого класса, а затем вызывает DescribeCar на каждом экземпляре.

TestCars1 формирует следующие выходные данные. Обратите особое внимание на результаты для car2 , который, вероятно, не соответствует ожидаемым. Тип объекта — ConvertibleCar , но DescribeCar не получает доступа к версии ShowDetails , определенной в классе ConvertibleCar , так как этот метод объявлен с модификатором new , а не override . В результате объект ConvertibleCar отображает то же описание, что и объект Car . Сравните результаты для car3 , который является объектом Minivan . В этом случае метод ShowDetails , объявленный в классе Minivan , переопределяет метод ShowDetails , объявленный в классе Car , и отображается описание микроавтобуса.

TestCars2 создает список объектов, имеющих тип Car . Значения объектов создаются из классов Car , ConvertibleCar и Minivan . DescribeCar вызывается для каждого элемента списка. В следующем коде показано определение TestCars2 .

Выводится следующий результат. Обратите внимание, что он совпадает с выходными данными, отображаемыми TestCars1 . Метод ShowDetails класса ConvertibleCar не вызывается, независимо от того, является ли тип объекта ConvertibleCar , как в TestCars1 , или Car , как в TestCars2 . И наоборот, car3 вызывает метод ShowDetails класса Minivan в обоих случаях, независимо от того, какого они типа — Minivan или Car .

Методы TestCars3 и TestCars4 завершают пример. Эти методы вызывают ShowDetails напрямую: сначала из объектов, объявленных с типом ConvertibleCar и Minivan ( TestCars3 ), а затем из объектов, объявленных с типом Car ( TestCars4 ). Следующий код определяет эти два метода.

Методы производят следующий результат, который соответствует результатам из первого примера в этой теме.

📎📎📎📎📎📎📎📎📎📎