![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Виртуальные методы
В этом уроке мы рассмотрим с вами некоторые инструменты, с помощью которых в Си-шарп реализуется полиморфизм - виртуальные методы, переопределение методов. Виртуальный метод – это метод, который может быть переопределен в классе наследнике. Переопределение метода – это изменение его реализации в классе наследнике. Переопределив метод, он будет работать по-разному в базовом классе и классе наследнике, имея при этом одно и то же имя и аргументы и тип возврата. Виртуальный метод объявляется при помощи ключевого слова virtual: [модификатор доступа] virtual [тип] [имя метода] ([аргументы]) { // тело метода } Объявив виртуальный метод, мы теперь можем переопределить его в классе наследнике. Для этого используется ключевое слово override: [модификатор доступа] override [тип] [имя метода] ([аргументы]) { // новое тело метода } Рассмотрим это на примере. У нас есть класс Человек, и от него наследуются еще два – Студент и Ученик. В базовом классе есть виртуальный методShowInfo, который выводит информацию об объекте. В классах Студент иУченик этот метод переопределяется для того, чтобы к выводу базовой информации добавить еще специфическую, относящуюся к соответствующему классу: class Person { public string Name { get; set; } public int Age { get; set; } public Person(string name, int age) {Name = name; Age = age; } public virtual void ShowInfo() //объявление виртуального метода { Console.WriteLine(" Человек\nИмя: " +Name+" \n" +" Возраст: " + Age + " \n"); } }
class Student: Person { public string HighSchoolName { get; set; } public Student(string name, int age, string hsName): base(name, age) { HighSchoolName = hsName; } public override void ShowInfo() // переопределение метода { Console.WriteLine(" Студент\nИмя: " + Name + " \n" + " Возраст: " + Age +" \n" +" Название ВУЗа: " + HighSchoolName + " \n"); } } class Pupil: Person { public string Form { get; set; } public Pupil(string name, int age, string form): base(name, age) { Form = form; } public override void ShowInfo() // переопределение метода { Console.WriteLine(" Ученик(ца)\nИмя: " + Name + " \n" + " Возраст: " + Age + " \n" + " Класс: " + Form + " \n"); } } class Program { static void Main(string[] args) { List< Person> persons = new List< Person> (); persons.Add(new Person(" Василий", 32)); persons.Add(new Student(" Андрей", 21, " МГУ")); persons.Add(new Pupil(" Елена", 12, " 7-Б")); foreach (Person p in persons) p.ShowInfo(); Console.ReadKey(); } } В методе main мы создаем список людей, в который добавляем просто человека, студента и ученика, и дальше выводим информацию о каждом из них вызовом метода ShowInfo(). Результат работы – вывод информации соответственно типу объекта. А теперь может возникнуть вопрос – а что будет, если убрать переопределение, откинув ключевые слова virtual и override? В таком случае, в базовом классе и в классе наследнике будут методы с одинаковым именемShowInfo. Программа работать будет, но о каждом объекте, независимо это просто человек или студент/ученик, будет выводиться информация только как о простом человеке (будет вызываться метод ShowInfo из базового класса). Это можно исправить, добавив проверки на тип объекта, и при помощи приведения типов, вызывать нужный метод ShowInfo: foreach (Person p in persons) { if (p is Student) ((Student)p).ShowInfo(); else if (p is Pupil) ((Pupil)p).ShowInfo(); else p.ShowInfo(); } Только вот, сколько лишнего кода от этого появляется. Думаю, становится понятно, что нам дают виртуальные методы и переопределение.
|