Переопределение методов в C#

В настоящее время я изучаю C# самостоятельно после изучения Java в течение всего семестра.

Одной из особенностей Java (или объектно-ориентированного программирования в целом) является возможность переопределения методов, которые унаследованы в подклассе.

Когда я изучал эту функцию в C#, я пытался самостоятельно переопределить метод, не изучая, как правильно переопределять методы в C#, и, похоже, это сработало.

Однако при дальнейшем изучении я узнал, что нам нужно использовать ключевое слово virtual при объявлении метода в суперклассе и override при переопределении метода в подклассе.

Итак, мой вопрос:
Как правильно переопределять методы в C#?

Дополнительное примечание: Мне также интересно, применим ли тот же случай к методам перегрузки в C#.

Ключевое слово virtual означает «Это реализация по умолчанию, которую можно переопределить». Ключевое слово abstract означает «Это всегда должно быть переопределено». По понятным причинам вы не можете использовать abstract, если класс также не является abstract. Правильный путь зависит от того, что вам нужно.

Cleptus 23.07.2019 12:31

Я не смог найти прямой вопрос по этому поводу в Stackoverflow, я собирался ответить.

Code Name Jack 23.07.2019 12:32

@CodeNameJack Там некоторые, ни один из них особо не проголосовал. Угадайте, что большинство вопросов получают комментарии со ссылками на справочник по языку Microsoft.

Cleptus 23.07.2019 12:35

Я бы посоветовал проверить ссылка на виртуальные ключевые слова и посмотреть на его ограничения, это даст вам хорошую основу для того, как и когда переопределить.

Cleptus 23.07.2019 12:45

Я бы предложил модификатор переопределения Справочник по C# - там все сказано о том, как переопределить

Sir Rufo 23.07.2019 12:47

@SirRufo Это не объясняет виртуальный модификатор, я добавил ответ не только с переопределением, но и с остальными модификаторами наследования и образцом

Cleptus 23.07.2019 13:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
803
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Следующее взято из Википедии (см. здесь, раздел C#).

«C# поддерживает переопределение методов, но только если явно запрошено с помощью модификаторов override и либо virtual, либо abstract.*)

abstract class Animal {
  public          String Name {get; set; }
  // Methods
  public          void   Drink();
  public virtual  void   Eat();
  public          void   Go();
}

class Cat : Animal {
  public new      String Name {get; set; }
  // Methods
  public          void   Drink();  // warning: hides inherited drink(). Use new
  public override void   Eat();    // overrides inherited eat().
  public new      void   Go();     // hides inherited go().
}

При переопределении одного метода другим сигнатуры двух методов должны быть идентичными (и иметь одинаковую видимость). В C# можно переопределить методы класса, индексаторы, свойства и события».


*) Как правильно упомянул Брэдбери9, на странице Википедии есть ошибка, поэтому я немного изменил ответ (добавил текст, выделенный жирным шрифтом выше)

Цитата из вики неверна. Это правда, что это должно быть явно объявлено, но оно должно читаться как «и virtual или abstract». Как бы то ни было, в нем отсутствует ключевое слово abstract. Я бы посоветовал вам отредактировать вики и свой ответ или изменить ссылку на ссылку MS.

Cleptus 23.07.2019 13:14

@bradbury9 - Спасибо за подсказку, вы абсолютно правы. Я изменил ответ и добавил сноску. Кроме того, я обновил текст Википедии.

Matt 23.07.2019 14:53
Ответ принят как подходящий

Существует два разных способа переопределения в .net в зависимости от того, хотите ли вы предоставить реализацию по умолчанию или нет.

Есть и другие ключевые слова, связанные с наследованием, такие как:

Пример:

public abstract class Bank
{
    public abstract string Country { get; } // Everything inheriting must implement it
    public virtual decimal TaxPercent { get { return 0.25; } } // Implementing it is optional
    public decimal DeclareTaxes()
    {
        decimal taxesToPay = 4000 * TaxPercent;
        return taxesToPay;
    }
}

public sealed class BahamasBank: Bank
{
    public override string Country { get { return "Bahamas"; }
    public override TaxPercent { get { return 0.0; } } // Bahamas is different from most countries in tax related stuff
}

public sealed class CanadaBank: Bank
{
    public override string Country { get { return "Canada"; }
}

Другие вопросы по теме