ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 3180

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Чтобы сэкономить место, можно освободиться от этой глупой концепции — "микрон] новая печь". Для приготовления закуски хватит и внутренностей печи. Тогда в инструкции достаточно написать примерно следующее: "Поместите полуфабрикат в ящик. Соедини красный и черный провод. Установите на трубе излучателя напряжение в 3000 вольт. Дол появиться негромкий гул. Постарайтесь не стоять близко к установке, если хотите иметь ц тей". Простая и понятная инструкция!

Но такой функциональный подход создает некоторые проблемы.

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

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

Невозможно использовать повторно. Печи предназначены для приготовлен! разных блюд. Вряд ли кому-то захочется создавать новую печь всякий раз при а обходимости приготовить новое блюдо. Если задача уже решена, неплохо исши зовать ее решение и в других программах.

Объект должен быть способен спроектировать внешний интерфейс максимально прс стым при полной достаточности для корректного функционирования. Если интерфа" устройства будет недостаточен, все кончится битьем кулаком или чем-то более тяжела по верхней панели такого устройства или просто разборкой для того, чтобы добраться» его внутренностей (что наверняка окажется нарушением законодательства об интелла туальной собственности). С другой стороны, если интерфейс слишком сложен, весы сомнительно, что кто-то купит такое устройство (как минимум, вряд ли кто-то будет HI пользовать все предоставляемые интерфейсом возможности).

Люди постоянно жалуются на сложность видеомагнитофонов (впрочем, с переходо на управление с помощью экрана количество жалоб несколько уменьшилось). В эк устройствах слишком много кнопок с различными функциями. Зачастую одна и та i кнопка выполняет разные функции — в зависимости от того, в каком именно состояш находится в этот момент видеомагнитофон. Кроме того, похоже, невозможно найти я видеомагнитофона различных марок с одинаковым интерфейсом.

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

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

228

Часть

IV.

Объектно-ориентированное

программирован


ние фарами оказалось там, где у всех "нормальных" автомобилей находится управление сигналами поворота. Отличие вроде бы небольшое, но я так и не научился поворачивать на этом автомобиле влево, не выключив при этом фары...

Кроме того, при хорошо продуманном дизайне автомобиля один и тот же элемент управления никогда не будет использоваться для выполнения более одной операции в за­ висимости от состояния автомобиля.

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

Поломке устройства. Какие бы рукоятки ни крутил ваш ребенок и какие бы кнопки не нажимал — микроволновая печь не должна от этого сломаться. После того как вы вернете все элементы управления в корректное состояние, она должна нормально работать.

К пожару или прочей порче имущества или нанесению вреда здоровью по­ требителя. Мы живем в сутяжном мире, и если бы что-то похожее могло про­ изойти — компании пришлось бы продать все вплоть до автомобиля ее президен­ та, чтобы рассчитаться с подающими на нее в суд и адвокатами.

Однако чтобы эти два правила выполнялись, вы должны принять на себя определен­ ную ответственность. Вы ни в коем случае не должны вносить изменения в устройство, в частности, отключать блокировки.

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

Аналогично, класс должен иметь возможность контролировать доступ к своим членамданным. Никакая последовательность вызовов членов класса не должна приводить программу к аварийному завершению, однако класс не в состоянии гарантировать это, если внешние объекты имеют доступ к внутреннему состоянию класса. Класс должен иметь возможность прятать критические члены-данные и делать их недоступными для внешнего мира.

Итак, как же С# реализует объектно-ориентированное программирование? Впрочем, это не совсем корректный вопрос. С# является объектно-ориентированным языком про-

Глава 10. Что такое объектно-ориентированное программирование

229



граммирования, но не реализует его — это делает программист. Как и на любом другом гом языке, вы можете написать на С# программу, не являющуюся объект! ориентированной (например, вставив весь код Word в функцию M a i n O ) . Иногда нужно писать и такие программы, но все же главное предназначение С# — создает объектно-ориентированных программ.

С# предоставляет программисту следующие необходимые для написания объект! ориентированных программ возможности.

Управляемый доступ. С# управляет обращением к членам класса. Ключе» слова С# позволяют объявить некоторые члены открытыми для всех, а другие защищенными или закрытыми. Подробнее эти вопросы рассматриваются в гла ве 11, "Классы".

Специализация. С# поддерживает специализацию посредством механизма, i вестного как наследование классов. Один класс при этом наследует члены друга класса. Например, вы можете создать класс Саг, как частный случай класса Vi h i c l e . Подробнее эти вопросы рассматриваются в главе 12, "Наследование".

Полиморфизм. Эта возможность позволяет объекту выполнить операцию так, как это требуется для его корректного функционирования. Например, класс Rocket унаследованный от V e h i c l e , может реализовать операцию S t a r t совершенно иначе, чем Саг, унаследованный от того же V e h i c l e . По крайней мере, будем надеяться, что это справедливо хотя бы по отношению к вашему автомобилю хотя с некоторыми автомобилями никогда ни в чем нельзя быть уверенным...| просьг полиморфизма рассматриваются в главах 13, "Полиморфизм", 1 "Интерфейсы и структуры".

230

Часть IV.

Объектно-ориентированное программировал

Глава 11

Классы

У Защита класса посредством управления доступом

>Инициализация объекта с помощью конструктора

>Определение нескольких конструкторов в одном классе

>Конструирование статических членов и членов класса

ласе должен сам отвечать за свои действия. Так же как микроволновая печь не должна вспыхнуть, объятая пламенем, из-за неверного нажатия кнопки, так и класс не должен скончаться (или прикончить программу) при предоставлении не­

корректных данных.

Чтобы нести ответственность за свои действия, класс должен убедиться в корректно­ сти своего начального состояния и в дальнейшем управлять им так, чтобы оно всегда ос­ тавалось корректным. С# предоставляет для этого все необходимое.

Простые классы определяют все свои члены как p u b l i c . Рассмотрим программу BankAccount, которая поддерживает член-данные b a l a n c e для хранения информа­ ции о балансе каждого счета. Сделав этот член p u b l i c , вы допускаете любого в святая святых банка, позволяя каждому самому указывать сумму на счету.

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

Управление доступом дает возможность избежать больших и малых ошибок в работе банка. Обычно программисты, привыкшие к функциональному про­ граммированию, говорят, что достаточно лишь определить правило, согласно которому никакие другие классы не должны обращаться к члену b a l a n c e не­ посредственно. Увы, теоретически это, может быть, и так, но на практике такой подход никогда не работает. Да, программисты начинают работу, будучи пере­ полненными благими намерениями, которые вскоре непонятно куда исчезают под давлением сроков сдачи проекта...


Пример программы с использованием открытых членов

В приведенной демонстрационной программе класс BankAccount объяв ляет все методы как public, в то же время члены-данные nAccountNumber и dBalance сделаны private. Эта демонстрационная программам

корректна и не будет компилироваться, так как создана исключительно в дидактических целях.

//

BankAccount - создание банковского счета с использованием

//

переменной типа double для хранения баланса

счета (она

//

объявлена как

p r i v a t e , чтобы скрыть баланс

от

внешнего

//

мира)

 

 

 

 

//

П р и м е ч а н и е : пока в программу не будут внесены

 

//

исправления,

она не будет

компилироваться,

так

как

//

функция Main() обращается

к private - член у класса

// B a n k A c c o u n t . usin g System;

namespace BankAccount

{

public class Program

{

public static v o i d Main(string[] args)

{

Console . WriteLine("В текущем состоянии эта " + "программа не к о м п и л и р у е т с я . " ) ;

//Открытие банковского счета

Console . WriteLine("Создание объекта " +

 

"банковского

с ч е т а " ) ;

BankAccount ba = n e w B a n k A c c o u n t ( ) ;

b a . I n i t B a n k A c c o u n t ( ) ;

 

//

Обращение к балансу при помощи метода Deposit()

//

вполне к о р р е к т н о ; Deposit()

имеет право доступа ко

//всем членам - данным b a . D e p o s i t ( 1 0 ) ;

//Непосредственное обращение к члену - данны м вызывает

//ошибку компиляции

Console . WriteLine("Здесь вы получите " + "ошибку к о м п и л я ц и и " ) ;

ba . dBalance += 1 0 ;

// Ожидаем подтверждения пользователя Console . WriteLine("Нажмите <Enter> для " +

"завершения программы .. . ") ;

C o n s o l e . R e a d ( ) ;

} }

//BankAccount - определение класса, представляющего

//простейший банковский счет

public class BankAccount

232

Часть

IV.

Объектно-ориентированное

программирование