Напомним, что наследование позволяет расширять поведение базового (родительского) класса, наследуя основную функциональность в производном подклассе (также именуемом дочерним классом).
Полиморфизм обозначает способность языка трактовать связанные объекты в сходной манере. Виртуальный метод — это метод, который с тем же именем в классе-наследнике может быть (но может и не быть) изменен (переопределен).
Рассмотрим простой пример. Создадим класс «Яблоко» с двумя полями (форма и размер) с модификатором protected и двумя методами, позволяющими задавать эти поля и извлекать их при необходимости. Создадим дочерний класс «Зеленое яблоко», добавив 3 поле — сорт, имена методов класса наследуются от родительского класса, однако их содержание будет изменено.
Разместим на форме два визуальных элемента listBox1 и button1 («Выполнить»), связав ее (кнопку) с методом button1_Click( ).
Текст файла Form1.cs :
using System; using System.Windows.Forms; namespace Наследование_и_Полиморфизм { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Apple яблоко1 = new Apple(); // объект1 класса Apple яблоко1.Apple_Set("круглое", 11.5); // задаем его поля GreenApple яблоко2 = new GreenApple(); // объект2 класса GreenApple яблоко2.Apple_Set("бочонок", 8.3,"курское золотое"); // его поля double d; string f, s; // для извлечения полей объектов яблоко1.Get_fields(out f, out d); // получить поля объекта1 listBox1.Items.Add("Яблоко " + f + " - " + d + " см"); яблоко2.Get_fields(out f, out d, out s); // получить поля объекта2 listBox1.Items.Add("Яблоко "+f+" - "+d+" см,"+" сорт - "+s); яблоко2.Get_fields(out f, out d); // получить поля объекта2 через метод родительского класса listBox1.Items.Add("Яблоко " + f + " - " + d + " см"); } } // родительский класс Яблоко - два поля, два метода public class Apple { protected string форма; // защищенные поля и с наследованием protected double размер; // не public !!! public void Apple_Set(string formа, double size) // задать поля { форма=formа; размер=size; } public void Get_fields(out string forma, out double size) // извлечь { forma = форма; size = размер; } } // дочерний класс Зеленое яблоко - три поля, два метода public class GreenApple : Apple // Наследование от класса Apple { protected string сорт; // дополнительное поле // 1-й полиморфный метод public void Apple_Set(string forma, double size, string sort) { Apple_Set(forma, size); // вызов базового метода сорт = sort; // для третьего поля - пересылка } // 2-й полиморфный метод public void Get_fields(out string forma,out double size,out string sort) { Get_fields(out forma, out size); // вызов базового метода sort = сорт; } } }
После однократного нажатия кнопки «Выполнить» получим следующий результат:
Выводы:
1) методы в обоих классах имеют одинаковые имена, но разное число параметров (два и три);
2) при создании дочернего класса новое поле просто добавилось к двум уже имеющимся полям;
3) все поля объектов являются защищенными, они не могут быть вызваны непосредственно, например, так: яблоко2.сорт;
4) В коде методов дочернего класса используется вызов аналогичных методов родительского класса;
5) Не запрещен вызов метода родительского класса для объекта дочернего класса: яблоко2.Get_fields(out f, out d); Результат — возврат (модификатор out) двух полей дочернего класса.
Механизм наследования позволяет развивать классы, а полиморфизм — избежать множество имен для однотипных методов в родительском классе и классах-наследниках.
Полиморфизм методов в C# реализован также в форме перегрузки методов.
NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.
![]() |
![]() |
![]() |
![]() |
Вот зачем вы используете русские имена для переменных? Это очень тупо!
У меня получилось вот что:
Ошибка CS1061
«Form1» не содержит определения «Form1_Load», и не удалось найти доступный метод расширения «Form1_Load», принимающий тип «Form1» в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).