Виртуальный метод — метод класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения.
Таким образом, программисту необязательно знать точный тип объекта для работы с ним. Достаточно лишь знать, что объект принадлежит классу или наследнику класса, в котором метод объявлен.
Естественно, что интерфейсы виртуального метода и всех его версий должны полностью совпадать. Таким образом, применение виртуальных методов позволяет фиксировать интерфейс метода и потом разработать под этот интерфейс новые реализации.
В основе полиморфизма для семейства классов, лежат три механизма:
// описываем переменную t // родительского класса Triangle t; // создаем объект t дочернего класса и // присваиваем его переменной // родительского класса t= new Equilateral(x); |
// метод будет переопределяться в дочернем классе, // поэтому в родительском указывается virtual virtual public double Sqr() // в дочернем классе переопределяемый метод // указывается со спецификацией override override public double Sqr() |
// описываем переменную t родительского класса Triangle t; // можно создать объект t дочернего класса t= new Equilateral(x, y, z); // или объект t родительского класса t= new Triangle (x, y, z); // при обращении к виртуальному методу Sqr, // он будет вызываться из того класса к которому // принадлежит объект s = t.Sqr(); |
Создадим класс Trapezoid, описывающий трапецию по четырем сторонам. Этот класс будет родительским.
В этом классе будет метод Perimeter вычисляющий периметр, метод Sqr вычисляющий площадь и метод Print, выводящий значения полей на экран.
Создадим дочерний класс Isoscelesl, описывающий равнобедренную трапецию по ее основаниям и боковой стороне.
Допустим, мы хотим для равнобедренных трапеций по-другому вычислять площадь.
Сделаем новый класс Isoscelesl потомком класса Trapezoid и сделаем метод Sqr (вычисление площади) виртуальным.
Пусть в дочернем классе будет еще свой метод, вычисляющий радиус вписанной окружности.
Для того чтобы вызвать собственный метод Radius из дочернего класса, кроме объекта t, пришлось создать еще один объект t1 дочернего класса и применить к нему этот метод. Это пришлось сделать потому, что переменная t у нас объявленна как Trapezoid, а в этом классе нет метода Radius.
Отработка для равнобедренной трапеции
Отработка для обычной трапеции