При рассмотрении основ объектно-ориентированного программирования упоминалось переопределение методов. Итак, давайте разберемся, что это такое, и с чем это употребляют. По сути, это крайне удобный механизм. При помощи переопределения метода мы можем расширить его функциональность в дочерних классах. А при необходимости метод родительского класса может быть полностью переписан.
Чтобы сказать системе, что нам нужна возможность переопределить метод, нужно использовать слово virtual. К примеру, при описании класса Object метод ToString() имеет подобную запись.
public virtual string ToString()
Отметив метод словом virtual мы оповещаем систему, что метод может быть переопределен в любом наследнике. А учитывая возможность построения древовидной структуры наследования — возможность переопределения будет очень полезной фичей. Вернемся к примеру класса «Персонаж». Переопределим для него метод ToString().
/// <summary> /// Переопределение метода ToString() /// </summary> /// <returns> Приведение к строке.</returns> public override string ToString() { return $"Персонаж:{Name} с силой {Strength} и ловкостью {Agility}"; }
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
Рассмотрим пример использования переопределенного метода.
Character character = new Character("Конан", "Мужской", 50, 7, 120); Console.WriteLine(character.ToString()); Object obj = character; Console.WriteLine(obj.ToString());
Вызвав приведение к строке у экземпляра класса, мы стопроцентно получим результат работы переопределенного метода. А что будет во втором случае? Тут все напрямую зависит от того, как мы переопределили метод.
override
Если было использовано это ключевое слово, на выходе будет использоваться переопределенный метод. Вне зависимости от того, как было оформлено обращение к методу.
new
Использование этого ключевого слова говорит системе о том, что мы не хотим перекрыть реализацию метода в базовом классе. То есть, при необходимости сможем получить доступ к методу предка. Рассмотрим переопределение метода при помощи слова new. В качестве примера перегрузим еще один метод класса Object.
/// <summary> /// Переопределение метода сравнения. /// </summary> /// <param name="obj"> Объект, с которым сравниваем.</param> /// <returns></returns> public new bool Equals(Object obj) { Character character = (Character)obj; return Name == character.Name && Gender == character.Gender && Strength == character.Strength && Agility == character.Agility && Health == character.Health; }
Как вы видите, в методе мы проводим простое сравнение свойств переданного объекта, с объектом вызвавшим метод. Вместо override мы использовали new потому, как знаем, что не нужно перекрывать функциональность метода родителя.
/// <summary> /// Сравнить персонажей. /// </summary> /// <param name="firstCharacter"> Первый персонаж.</param> /// <param name="secondCharacter"> Второй персонаж.</param> /// <returns></returns> public static string Compare(Character firstCharacter, Character secondCharacter) { bool equalParams = firstCharacter.Equals(secondCharacter); Object obj = firstCharacter; bool fullEqual = obj.Equals(secondCharacter); if (equalParams) { return "Одинаковые свойства"; } if (fullEqual) { return "Абсолютно идентичны"; } return "Разные объекты"; }
Итак, в чем же фишка? Когда мы вызовем сравнение двух персонажей, будет вызван переопределенный метод. Следовательно сравнение будет проведено по свойствам. Если же сравнение вызвать из obj, на выходе будет результат сравнения двух объектов на полную идентичность. Если бы мы использовали ключевое слово override, вызвать родительский метод уже не получилось бы.
Переопределение методов C# — Итоги
Пожалуй, это необходимый минимум, которым следует владеть для переопределения методов. Удачных вам экспериментов, коллеги.
Кроме того, рекомендую прочитать статью Паттерн Состояние C#. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.