Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
стас.docx
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
51.26 Кб
Скачать

2. Полиморфизм

Полиморфизм (polymorphism) (от греческого polymorphos) - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач. Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование одного имени для задания общих для класса действий. Выполнение каждого конкретного действия будет определяться типом данных. Например для языка Си, в котором полиморфизм поддерживается недостаточно, нахождение абсолютной величины числа требует трёх различных функций: abs(), labs() и fabs(). Эти функции подсчитывают и возвращают абсолютную величину целых, длинных целых и чисел с плавающей точкой соответственно. В С++ каждая из этих функций может быть названа abs(). Тип данных, который используется при вызове функции, определяет, какая конкретная версия функции действительно выполняется. В С++ можно использовать одно имя функции для множества различных действий. Это называется перегрузкой функций (function overloading).

В более общем смысле, концепцией полиморфизма является идея "один интерфейс, множество методов". Это означает, что можно создать общий интерфейс для группы близких по смыслу действий. Преимуществом полиморфизма является то, что он помогает мнижать сложность программ, разрешая использование того же интерфейса для задания единого класса действий. Выбор же конкретного действия, в зависимости от ситуации, возлагается на компилятор. Вам, как программисту, не нужно делать этот выбор самому. Нужно только помнить и использовать общий интерфейс. Пример из предыдущего абзаца показывает, как, имея три имени для функции определения абсолютной величины числа вместо одного, обычная задача становится более сложной, чем это действительно необходимо.

  Полиморфизм может применяться также и к операторам. Фактически во всех языках программирования ограниченно применяется полиморфизм, например, в арифметических операторах. Так, в Си, символ + используется для складывания целых, длинных целых, символьных переменных и чисел с плавающей точкой. В этом случае компилятор автоматически определяет, какой тип арифметики требуется. В С++ вы можете применить эту концепцию и к другим, заданным вами, типам данных. Такой тип полиморфизма называется перегрузкой операторов (operator overloading).

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

В приведенном ниже классе, будут созданы объекты и помещены в коллекцию фигур, а далее при помощи полиморфизма будут вызваны методы конкретного объекта даже не глядя на то что все они помещены в список абстрактных фигур. Правда доступны будут только общие свойства и методы для всех экземпляров.

ShapeManager.cs:

using System;

using System.Collections.Generic;

namespace OOPLibrary.Shape

    <summary>

     Класс управления фигурами.

     </summary>

    public class ShapeManager

        private Circle _circle;

        private Rectangle _rectangle;

        private Triangle _triangle;

        private List<Shape> _shapes;

        Конструктор класса, в нем создаются первоначальные объекты

        public ShapeManager()

            Создаем объект круг

            circle = new Circle();

            Создаем объект прямоугольник

            rectangle = new Rectangle();

            Создаем объект треугольник

            triangle = new Triangle();

            Невозможно создать объект из абстрактного класса фигуры,

            но можно создать объекты из его наследников: круга, прямоугольника и треугольника,

            а также можно создать список и з абстрактных фигур, и положить в него объекты

            наследников, но при проходе этого списка в цикле будут доступны только

            общие поля и методы из абстрактоного класса Shape

            Shape shape = new Shape(); Ошибка компилятора

             Создаем список фигур, в него можно положить те объекты, которые отнаследованы от класса Shape

            shapes = new List<Shape>();

            shapes.Add(_circle);        добавляем круг в список фигур

            shapes.Add(_rectangle);     добавляем прямоугольник в список фигур

            shapes.Add(_triangle);      добавляем треугольник в список фигур

         <summary>

        Метод вывводит информацию о круге

         </summary>

        private void ProntCircleInfo()

            Console.WriteLine(_circle.Name);

            Console.WriteLine("X1: " + _circle.X1);

            Console.WriteLine("Y1: " + _circle.Y1);

            Console.WriteLine("Радиус: " + _circle.Radius);

            _circle.Draw();

            Console.WriteLine();

         <summary>

         Метод вывводит информацию о прямоугольнике

         </summary>

        private void PrintRectangleInfo()

            Console.WriteLine(_rectangle.Name);

            Console.WriteLine("X1: " + _rectangle.X1);

            Console.WriteLine("Y1: " + _rectangle.Y1);

            Console.WriteLine("X2: " + _rectangle.X2);

            Console.WriteLine("Y2: " + _rectangle.Y2);

            _rectangle.Draw();

            Console.WriteLine();

         <summary>

         Метод вывводит информацию о треуголнике

         </summary>

        private void PrintTriangleInfo()

            Console.WriteLine(_triangle.Name);

            Console.WriteLine("X1: " + _triangle.X1);

            Console.WriteLine("Y1: " + _triangle.Y1);

            Console.WriteLine("X2: " + _triangle.X2);

            Console.WriteLine("Y2: " + _triangle.Y2);

            Console.WriteLine("X3: " + _triangle.X3);

            Console.WriteLine("Y3: " + _triangle.Y3);

            _triangle.Draw();

            Console.WriteLine();

         <summary>

         Метод выводит общую информацию для всех наследников,

         находящихся в списке фигур

         </summary>

        private void PrintCommonShapeInfo()

            foreach (var shape in _shapes)

     общие свойства доступны для всех фигур (Name и Paper).

                независимо от того какая конкретная фигура, будет находится

                в данный моемент в переменно shape доступ к ее полям,

                например X1, Y1, Radius будут недоступны без предварительного

                явного приведения к конкретному типу (Circle, Triangle...)

                Console.WriteLine(String.Format("{0} будет нарисован на '{1}'...", shape.Name, shape.Paper));

                метод доступен для всех фигур, но при помощи полиморфизма,

                он перекрты в каждом наследнике, таким образом,

                чтобы каждый объект мог реализовать свой механизм отрисовки самомго себя.

                поэтому в runtime будет подставлен нужный метод конкретного наследника,

                несмотря на то, что список хранит абстрактные фигуры

                shape.Draw();

                Console.WriteLine();

         <summary>

         Метод запускает проверку методов и свойств фигур и их наследников.

         </summary>

        public void Run()

             выводим информацию, доступную для круга

            ProntCircleInfo();

             выводим информацию, доступную для прямоугольника

            PrintRectangleInfo();

             выводим информацию, доступную для треугольника

            PrintTriangleInfo();

             проверяем возможности полиморфизма

            PrintCommonShapeInfo();