|
Программирование >> Обработка исключительных ситуаций
Console.Wri teLi ne(X.GetTypeC)); Результат работы программы: X != Y X * Z X Equals Y ConsoleAppli cati onl.Monster В методе Equals сначала проверяется переданный в него аргумент. Если он равен nul 1 или его тип не соответствует типу объекта, вызвавшего метод, возвращается значение false. Значение true формируется в случае попарного равенства всех полей объектов. Метод GetHashCode просто делегирует свои функции соответствующему методу одного из полей. Метод ToString формирует форматированную строку, содержащую значения полей объекта. Анализируя результат работы программы, можно увидеть, что в операции сравнения на равенство сравниваваются ссылки, а в перегруженном методе Equals - значения. Для концептуального единства можно переопределить и операции отношения, соответствующий пример приведен в разделе Перегрузка операций отношения (см. с. 203). Рекомендации по программированию Наследование классов предоставляет программисту богатейшие возможности организации кода и его многократного использования. Выбор наиболее подходящих средств для целей конкретного проекта основывается на знании механизма их работы и взаимодействия. Наследование класса Y от класса X означает, что Y представляет собой разновидность класса X, то есть более конкретную, частную концепцию. Базовый класс 1 является более общим понятием, чем Y1. Везде, где можно использовать X, можно использовать и Y, но не наоборот (вспомните, что на место базового класса можно передавать любой из производных). Необходимо помнить, что во время Например, каждый программист - человек, но не каждый человек - программист. Листинг 8.5 (продолжение) if ( X == Z ) Console.WriteLineC X == Z ) ; else Console.WriteLineC X ! = Z ) ; if ( X.Equals(Y) ) Console.WriteLineC X Equals Y ); else Console.WriteLineC X not Equals Y ); выполнения программы не существует иерархии классов и передачи сообщений объектам базового класса из производных - есть только конкретные объекты классов, поля которых формируются на основе иерархии на этапе компиляции. Главное преимущество наследования состоит в том, что на уровне базового класса можно написать универсальный код, с помощью которого работать также с объектами производного класса, что реализуется с помощью виртуальных методов. Как виртуальные должны быть описаны методы, которые выполняют во всех классах иерархии одну и ту же функцию, но, возможно, разными способами. Пусть, например, все объекты иерархии должны уметь выводить информацию о себе. Поскольку эта информация хранится в различных полях производных классов, функцию вывода нельзя реализовать в базовом классе. Естественно назвать ее во всех классах одинаково и объявить как виртуальную с тем, чтобы ее можно было вызывать в зависимости от фактического типа объекта, с которым работают через базовый класс. Для представления общих понятий, которые предполагается конкретизировать в производных классах, используют абстрактные классы. Как правило, в абстрактном классе задается набор методов, то есть интерфейс, который каждый из потомков будет реализовывать по-своему. Обычные (не виртуальные) методы переопределять в производных классах не рекомендуется, поскольку производные классы должны наследовать свойства базовых, а спецификатор new, с помощью которого переопределяется обычный метод, разрывает отношение наследования на уровне метода. Иными словами, невиртуальный метод должен быть инвариантен относительно специализации, то есть должен сохранять свойства, унаследованные из базового класса независимо от того, как конкретизируется (специализируется) производный класс. Специализация производного класса достигается добавлением новых методов и переопределением существующих виртуальных методов. Альтернативным наследованию механизмом использования одним классом другого является вложение, когда один класс является полем другого. Вложение представляет отношения классов Y содержит X или Y реализуется посредством X . Для выбора между наследованием и вложением служит ответ на вопрос о том, может ли у Y быть несколько объектов класса X ( Y содержит X ). Кроме того, вложение используется вместо наследования тогда, когда про классы X и Y нельзя сказать, что Y является разновидностью X, но при этом Y использует часть функциональности X ( Y реализуется посредством X ). Глава 9 Интерфейсы и структурные типы В этой главе рассматриваются специальные виды классов - интерфейсы, структуры и перечисления. Синтаксис интерфейса Интерфейс является крайним случаем абстрактного класса. В нем задается набор абстрактных методов, свойств и индексаторов, которые должны быть реализованы в производных классах . Иными словами, интерфейс определяет поведение, которое поддерживается реализующими этот интерфейс классами. Основная идея использования интерфейса состоит в том, чтобы к объектам таких классов можно было обращаться одинаковым образом. Каждый класс может определять элементы интерфейса по-своему. Так достигается полиморфизм: объекты разных классов по-разному реагируют на вызовы одного и того же метода. Синтаксис интерфейса аналогичен синтаксису класса: [ атрибуты ] [ спецификаторы ] interface имя интерфейса [ : предки ] телоинтерфейса [ ; ] Для интерфейса могут быть указаны спецификаторы, new, publ i с, protected, internal и private. Спецификатор new применяется для вложенных интерфейсов и имеет такой же смысл, как и соответствующий модификатор метода класса. Остальные спецификаторы управляют видимостью интерфейса. В разных контекстах определения интерфейса допускаются разные спецификаторы. По умолчанию интерфейс доступен только из сборки, в которой он описан (internal). 1 Кроме того, в интерфейсе можно описывать события, которые мы рассмотрим в главе 10.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |