Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010) (1160865), страница 21
Текст из файла (страница 21)
На заметку! Инкапсуляция помогает достичь сплоченной работы объектов при слабой связности мекку ними. Доступность Ранее модификаторы доступа уже несколько раз упоминались. При наличии опыта работы с любым другим объектно-ориентированным языком программирования вроде С++ или Затя их применение может выглядеть интуитивно понятным. Однако некоторые нюансы доступа к членам в С№ и СЫ также заслуживают упоминания.
Прежде чем рассматривать различные типы модификаторов. давайте немного поговорим о том, где их можно применять. По сути, модификаторы доступа можно использовать почти с любой определенной сущностью в программе на С№, включая классы и любые члены внутри этих классов. Модификаторы доступа. применяемые к классу, касаются его видимости извне содержащей этот класс сборки. Модификаторы доступа, примененные к членам класса, включая методы, поля, свойства, события и индексаторы, влияют на видимость члена извне данного класса. В табл. 4.1 описаны различные модификаторы доступа, имеющиеся в С№.
Таблица 4.1. Модификаторы доступа а С№ Модификатор доступа Значение рц1г11с Член полностью видим как извне области определения, твк и внутри этой области. Другими словами, доступ к общедоступному члену вообще не ограничен. ргосессео Член видим только определяющему его классу и любому классу-нвспеднику данного класса.
1псегпа1 Член видим везде в пределах содерквщей его сборки. Сюда входит определяющий его класс и любая область внутри сборки, но вне данного класса. РгокескегГ 1псегпз1 Член видим внутри определяющего его класса и везде внутри сборки. Этот модификатор является комбинацией модификаторов р го се с.егг и впкегпа1 с использованием логической операции "ИЛИ". Член таске видим любому классу-наследнику определяющего его кпвссв, независимо от того, находится он в той же сборке или нвт.
ргвчаге Член видим только в определяющем классе, без исключений. Это — наиболее строгая форма доступа, и она принята по умолчанию дпя членов класса. Обратите внимание, что СЬВ поддерживает еще одну форму доступности, которую проектировщики языка С№ сочли необязательной для реализации. Внутри СЕК она известна как доступность семейсгпва и сборки. В терминологии С№ это соответствует ргосескесг и 1псегпа1, если по какой-то причине вам совершенно необходим такой модификатор доступа, то следует воспользоваться другим языком, таким как С++/СЫ или низкоуровневым П..
Классы, структуры и объекты 1Т Теперь давайте рассмотрим допустимое применение этих модификаторов к разным определенным сущностям внутри С№. Члены класса могут использовать пять вариантов модификаторов доступа С№. Доступом по умолчанию к членам класса в отсутствие всяких модификаторов является рг1часе. Типы, определенные внутри или вне пространства имен, могут иметь только два модификатора доступа: роЬ11с или 1пгегпа1. По умолчанию для них принято 1пкегпа1.
Модификаторы доступа роЬ11с, рг№чаге и 1псегпа1 можно применять к определению членов зггосг. Определение зтгосс подробно рассматривается в разделе "Определения типов значений" далее в настоящей главе. Обратите внимание на отсутствие модификаторов ргогесгегт и ргогесгег1 1псегпа1. Здесь они не нужны, поскольку зтгиск по умолчанию герметизированы (зеа1егт) — в том смысле, что они не могут служить базовыми классами для наследования. Модификатор эеа1ео будет рассмотрен более подробно в разделе "терметизированные классы". На заметку! Еще одно званое замечание для тех, кто работал на С++: члены зсгисс являются рг№часе по умолчанию — как в определении класса, тогда как в С++ они по умолчанию рсь11с.
И, наконец, члены интерфейсов, которые полностью описываются в главе 5, а также еполг, о которых шла речь в главе 3, по своей природе являются роЬ11с. Интерфейсы предназначены для определения набора операций, или контракта, который класс может реализовать. Для интерфейса не имеет смысла предусматривать какие-то члены с ограниченным доступом, поскольку члены с ограниченным доступом обычно ассоциируются с реализацией класса, а интерфейсы по определению реализации не содержат. Перечисления, с другой стороны.
обычно используются в качестве именованных коллекций констант. Они также не имеют внутренней реализации, так что ограничение доступа для них также не имеет смысла. В действительности, вы получите сообщением об ошибке, если специфицируете модификатор доступа вроде риЬ1№с для члена интерфейса или члена перечисления. Как видите, почти всегда доступом по умолчанию является наиболее ограниченный доступ, имеющий смысл для данной сущности. Другими словами, чтобы открыть другой доступ к классам или членам класса, потребуется приложить некоторые усилия. Единственное исключение — доступ к пространству имен, принятый по умолчанию как роЬ11с и не допускающий указания каких-либо модификаторов доступа.
Интерфейсы Несмотря на то что большая часть главы 5 посвящена теме интерфейсов, их стоит представить уже здесь, поскольку они понадобятся на протяжении оставшейся части этой главы. Вообще говоря, инптерсбегтс — это определение контракта. Классы могут реализовывать разные интерфейсы и за счет этого гарантировать выполнение требований контракта. Когда класс наследуется от интерфейса.
он обязан реализовать все члены этого интерфейса. Класс может реализовывать столько интерфейсов, сколько нужно; при этом интерфейсы перечисляются в списке базовых классов определения класса. В общих чертах синтаксис интерфейса очень похож на синтаксис класса. Однако каждый его член неявно имеет модификатор роЬ11с. Объявление любого члена интерфейса с каким-нибудь явным модификатором приведет к возникновению ошибки времени компиляции. Интерфейсы могут содержать только методы экземпляра; другими словами, включать статические методы в их определения нельзя.
Интерфейсы не содержат реализации. те. они по природе своей семантически абстрактны. Если вы знакомы с языком С++, то знаете, что там можно создать подобную конструкцию, объявляя класс, который содержит только общедоступные, чистые виртуальные методы. не имеющие реализаций по умолчанию. 78 Глава 4 Член интерфейса может состоять только из членов, которые в конечном итоге становятся методами в С).й. Сюда относятся методы, свойства, события и индексаторы. Об индексаторах речь пойдет в разделе "Индексаторы" далее в этой главе, а события рассматриваются в главе 10.
На заметку! Если вы — сторонник строгой терминологии, то знайте, что в спецификации СЕ свойства, события, индексаторы, операции, конструкторы и деструкторы на самом деле называются функциональными членамн. На самом деле было бы неправильно называть ик методами. Методы содержат исполняемый код, так что они тоже считаются функциональными членами. В следующем коде показан пример интерфейса и класса, реализующего интерфейс: рпЬ11с Тпгеггзсе 1Мпз1с(зп // Примечание: общепринятая практика заключается // в препварении имен интерфейсов заглавной буквой 1 ( чотб Р1аумпзус(); ) рчЬ11с с1ззз Та1епгебРегзоп: 1Мизбс1зп ( рпЬ11с чоьб Р1зуМпзус() () рпв11с чоьб Пол11ге1ерапсе() () рчЬ11с с1ззз Ептгуроапс згзгбс чоуб Ма(п() ( Та1епгебрегзоп бобе = пен Тз1епсебРегзоп()г 1Мпзбсаап щпз1с1ап = бобе; юпз1с1ап.р1аунпз1с О г бобе.Р1ауМпз1с()г бобе.ройь1гс1епапсе О; ) ) В приведенном примере определен интерфейс по имени 1Мпзбсап.
Класс Та1епсебрегзоп указывает, что он желает подцерживать интерфейс 1Мпзасап. Объявление класса на самом деле говорит: "Необходимо вступить в контракт для поддержки интерфейса 1Мпзбсагп при этом гарантируется подцержка всех методов этого интерфейса". Требование интерфейса заключается просто в поддержке метода Р1аумпзус, что исправно исполняет класс Та1епеебрегзоп. В заключение следует отметить, что типы интерфейсов обычно принято называть, начиная с заглавной буквы "1".
При чтении кода это служит маркером, указывающим, что тип с таким именем на самом деле является интерфейсом. Теперь клиенты могут обращаться к методу Р1зумцзбс одним из двух способов. Они могут либо вызывать его непосредственно через экземпляр объекта, либо получить интерфейсную ссылку на экземпляр объекта и вызвать метод через нее. Поскольку класс Та1епкебрегзоп пОдцерживает интеРфейс 1Мизусап, ссылки на объекты этого класса являются неявно преобразуемыми в ссылки на 1Мизбсап. В коде метода Ма(.п в предыдущем примере продемонстрирован вызов методов обоими способами.
Тема интерфейсов достаточно обширна, поэтому ей посвящена целая глава б. Тем не менее, приведенной здесь информации об интерфейсах вполне достаточно для облегчения освоения материала, представленного в оставшейся части данной главы. Классы, структуры и объекты 79 Наследование Большинство разработчиков считают наследование краеугольным камнем объектно-ориентированного программирования. Хотя наследование выглядит вполне простой концепцией для тех, кто впервые сталкивается с ним. утверждение о том, что наследование является краеугольным камнем, можно оспорить.
Некоторые склонны считать инкапсуляцию более строгой характеристикой объектно-ориентированного программирования. Наследование — зто важная концепция и полезный инструмент. Однако, как и множество других мощных инструментов, в случае неправильного применения оно может представлять опасность.










