- •Обзор элементов класса.
- •Класс Object
- •Структуры
- •Методы Ссылочные параметры ref и out
- •Переменное число аргументов метода
- •Перегрузка методов. Вызов методов с одинаковым именем и разными аргументами
- •Конструкторы экземпляра
- •Вызов конструктора экземпляра
- •Закрытые конструкторы экземпляра
- •Статические конструкторы
- •Конструкторы структур
- •Член со спецификатором readonly
- •Деструкторы. Сборка мусора
- •Объект Account
- •Объект Account недоступен
- •Свойства
- •Индексаторы
- •Предпосылки появления наследования
- •Синтаксис наследования.
- •Типы наследования
- •Множественное наследование
- •Наследование интерфейса
- •Виртуальные методы
- •Спецификаторы доступности
- •Вызов базовых версий функций
- •Абстрактные классы и функции
- •Структуры и наследование
- •Полиморфизм
- •Потеря и восстановление информации о типе
- •Операции is и as
- •Файловый ввод-вывод
- •Потоки данных и файловый ввод-вывод
- •Виды файлов
- •Классы файлового ввода-вывода
- •Класс FileInfo
- •Текстовый ввод-вывод при помощи Stream Reader и Stream Writer
- •Бинарный ввод и вывод при помощи класса FileStream
Предпосылки появления наследования
Предположим, что в программе требуется создать объект с атрибутами и функциональностью спортивный автомобиль, вседорожник,. Без наследования это можно сделать двумя способами:
-
Все три типа объектов можно рассматривать как автомобили и сделать все атрибуты общими. Таким образом, все три типа автомобилей будут экземплярами одного класса.
-
Можно поступить наоборот — создать три класса.
Оба подхода можно заставить работать, однако у каждого из них есть серьезные недостатки.
Рассмотрим первый подход. Графически он представлен на рис.10.2.
Атрибуты
и действия характерные для всех
автомобилей
Дополнительные
атрибуты и действия характерные для
спортивного авто
Дополнительные
атрибуты и действия характерные для
внедорожника
Класс Внедорожник_Спортивный
Рассмотрим основные недостатки первого подхода:
-
Трудно найти подходящее имя для класса. Проблемы начинаются с поиска имени. Класс включает не просто усредненные автомобили, поэтому имя «Автомобиль»не очень подходит.
-
Необходима переменная экземпляра, которая указывает, автомобиль какого типа представляет объект. Нужен способ узнать, какого типа автомобиль представляет конкретный объект.
-
Переменные экземпляра, которые используются только в одном из трех типов автомобилей, напрасно расходуют память, загромождают код и являются источником ошибок.
-
Функции-члены, которые используются только в одном из трех типов автомобилей, напрасно расходуют память, загромождают код и являются источником ошибок.
-
Функции-члены с одним и тем же именем в трех автомобилях имеют разные реализации, поэтому должны содержать конструкцию if...else для выполнения фрагмента кода в зависимости от того, для какого объекта вызывается метод.
Рассмотрим преимущества, которые возникают при использовании данного подхода.
-
Переменные экземпляра всех трех типов автомобилей содержится в одном месте, поэтому их не нужно копировать и ими легко управлять.
-
Функции-члены всех трех типов автомобилей содержатся в одном и том же месте, поэтому их не нужно копировать и легко модифицировать.
Из сказанного выше можно заключить, что попытка реализовать разные типы автомобилей одним классом имеет несколько преимуществ. Однако в целом это плохой подход, поскольку он порождает громоздкую задачу — разместить все три типа автомобилей в одном классе.
Создание трех разных классов представляется лучшим решением, но и оно сопровождается проблемами. Рассмотрим рисунок иллюстрирующий этот подход.
Рассмотрим основные преимущества и недостатки данного подхода.
Основной недостаток: атрибуты и действия, принадлежащие обобщенному классу автомобилей, должны присутствовать во всех классах. Если программисту требуется изменить или добавить метод присущий свеем автомобилям, то ему придется внести изменения во все классы.
Основное преимущество: уникальные атрибуты и действия содержатся в каждом классе.
Атрибуты и действия, присущие только одному из трех классов встроены в свои классы и не пересекаются с другими.
Обобщив сказанное можно сделать вывод, что два подхода приводят к следующей дилемме: элементы класса, общие для всех трех категорий автомобилей, хорошо обрабатываются при первом подходе, но вызывают проблемы при втором. А элементы, уникальные для каждой категории автомобилей, вызывают проблемы при первом подходе, но естественным образом обрабатываются при втором.
Описанные выше проблемы можно решить с использованием третьего подхода называемого наследованием. Графически этот подход изображен ниже.
Рассмотрим подробно последовательность действий, которые реализуют представленный рисунок. Вначале нужно создать класс «Автомобиль» с общими элементами, которые характерны для автомобилей разных видов. Затем два специализированных класса: «Внедорожник» и «Спортивный», содержащие только характеристики, уникальные для каждого типа автомобилей. Самое главное – создать механизм реализующий такую идею: помимо уникальных элементов каждый из специализированных классов должен содержать элементы класса «Автомобиль». Таким образом, требуется создать два новых класса, которые расширяют существующий класс «Автомобиль». При этом два производных класса наследуют свойства класса «Автомобиль» и в них добавляются уникальные свойства.
Механизм наследования обеспечивает реализацию описанного третьего подхода. Наследование используется для создания объектов, имеющих как общие, так и особые свойства. Когда класс «Спортивный» наследует элементы «Автомобиль», говорят, что класс «Спортивный»— производный от «Автомобиль», или «Спортивный»— прямой подкласс класса «Автомобиль». Класс «Автомобиль» называется базовым (а также подклассом или родительским классом) класса «Спортивный», поскольку он служит основой для «Спортивный».