Инкапсуляция и полиморфизм

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

public string FioInitials

{

get

{

string fio = Surname + " " + Name.Substring(0, 1) + ". " + Otchestvo.Substring(0, 1) + ".";

return fio;

}

}

Свойство класс Person со свойством FioInitials инкапсулирует в себе детали составления ФИО. Кстати говоря, это свойство не доделано даже для примитивного тестового примера, так как в нем не учитывается возможность того, что имя или отчество будет неизвестно, в таком случае оно просто вылетит с ошибкой.

Полиморфизм, если отбросить в сторону хитрую теорию, означает, что в реальности встречается много однотипных задач, отличающихся друг от друга только мелкими подробностями - например надо выполнить одни и те же действия над разными данными или получить одни и те же данные разными способами. Таким образом мы получаем много похожих друг на друга, но не одинаковых действий. Чуть выше мы ставили перед собой задачу узнать владельца груза (например чтобы потребовать с него плату) - для кота и человека она решалась по-разному. Поэтому мы создали базовый класс Cargo и два подкласса, по-разному реализующих эту задачу. Это и есть полиморфизм, в нижеприведенном куске кода мы используем полиморфизм на уровне классов, так как в списке грузов используются две разных реализации груза, по-разному получающие данные о владельце, но для нашего кода эти две разные реализации выглядят одинаково при обращении через базовый класс.

foreach (Cargo currCargo in cargoList)

{

Console.WriteLine("Вес " + currCargo.Mass + ", владелец " + currCargo.Owner.Fio);

}

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

На самом деле у функции Console.WriteLine целых 19 перегруженных вариантов, которые принимают разные типы данных или даже разные наборы данных, преобразовывают их в строку по определенным правилам и выводят в консоль.WriteLine() - не принимает никаких данных на вход и выводит пустую строку, WriteLine(String) - выводит собственно строку,WriteLine(Object) - выводит в консоль результат работы функции ToString данного класса, WriteLine(String, Object, Object) - выводит информацию о нескольких обьектах, форматируя ее согласно данным из строки первого аргумента.

Таким образом, когда мы переопределили унаследованный от Object метод ToString для класса Person

public override string ToString()

{

return Fio + ", вес " + Mass + " кг.";

}

и Cat

public override string ToString()

{

return Name + ", вес " + Mass + " кг., хозяин " + Master.Fio;

}

И потом использовали перегруженный вариант ToString в перегруженном варианте WriteLine через экземпляр базового для Person класса Cargo

foreach (Cargo currCargo in cargoList)

{

Console.WriteLine(currCargo);

}

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: