«C# для школьников УЧЕБНОЕ ПОСОБИЕ Книга выпускается при поддержке компании Microsoft Интернет-Университет БИНОМ. Информационных Технологий Лаборатория знаний ...»
Лицей информационных технологий
Мартин Дрейер
C# для школьников
УЧЕБНОЕ ПОСОБИЕ
Книга выпускается при поддержке компании Microsoft
www.microsoft.ru
www.dreamspark.ru
Интернет-Университет БИНОМ.
Информационных Технологий Лаборатория знаний
www.intuit.ru www.lbz.ru
Москва 2010 УДК 004.438.045C#(075.3) ББК 32.973.26-018.1C#.я721-1 Д73 Дрейер М.
Д73 C# для школьников: Учебное пособие / М. Дрейер. Перевод с англ. под ред. В. Биллига— М.: Интернет-Университет Информационных Технологий; БИНОМ. Лаборатория знаний, 2009. — 128 с.: ил., табл. — (Лицей информационных технологий).
ISBN 978-5-9963-0236-9 (БИНОМ.ЛЗ) Эта книга знакомит юного читателя (предполагаемый возраст — 12–16 лет) с объектно-ориентированным программированием, и автор предлагает начать обучение с реальных программ в среде Windows.
Новый язык программирования Microsoft C# (произносится «си-шарп») — очень мощный и в то же время простой в использовании. Он высоко ценится современными ИТ-специалистами и является хорошим выбором для тех, кто только ступает на путь программирования.
УДК 004.438.045C#(075.3) ББК 32.973.26-018.1C#.я721- Полное или частичное воспроизведение или размножение каким-либо способом, в том числе и публикация в Сети, настоящего издания допускается только с письменного разрешения представительства компании Microsoft в России.
По вопросам приобретения обращаться:
«БИНОМ. Лаборатория знаний»
Телефон (499) 157-1902, (499) 157-5272, e-mail: [email protected], http://www.Lbz.ru © Интернет-Университет Информационных Технологий, ISBN 978-5-9963-0236-9 (БИНОМ.ЛЗ) ©БИНОМ. Лаборатория знаний, Предисловие редактора перевода Читать, писать и считать мы учим детей, едва им исполнится 7 лет. Многие овладевают этими навыками значительно раньше – чтение в 4 года совсем не редкость. Относится ли и программирование к так называемым базисным умениям? Можно ли учиться этой премудрости с 7 лет? Полагаю, что в ближайшие десятилетия так и будет: программирование, как вторая грамотность, станет повсеместным явлением.
Знакомый мне победитель международной школьной олимпиады по информатике, теперь уже студент, свои первые программы написал еще во втором классе. Впрочем, не он один. По этой дороге идут многие школьники, и число их растет.
Когда маленькие девочки, играя в куклы, дают им имена — это Маша, а вот это Даша, — то, по сути, они занимаются именованием объектов, совсем как в объектно-ориентированном программировании. И говоря кукле Маше: «Если будешь себя хорошо вести, то я одену тебя в новое платье», они используют базисную конструкцию языков программирования — оператор If – then, а напоминая кукле Даше о том, что «уже 12 часов дня — пора спать», создают события и выполняют их обработку. В мире маленьких мальчиков работа с объектами идет столь же интенсивно.
Сегодня компьютер есть в каждом доме, и вполне обычное дело, когда ребенок, еще не умеющий толком читать, нажимает на кнопки, легко справляясь с компьютерными играми. Игры — хорошее дело, я и сам иногда увлекаюсь ими. Но если компьютер используется только для игр – это беда, болезнь.
Компьютер — инструмент для созидания. Чем раньше мы будем учиться созиданию, тем лучше. Быть потребителем готовых продуктов несложно, но чрезмерное потребление просто вредно.
Книг, предназначенных для юных программистов, совсем немного. И Мартин Дрейер написал одну из них. В ней есть забавные картинки, многочисленные примеры, читать ее интересно и полезно, даже тем, кто вовсе не собирается стать программистом.
Привлекая аналогии из реального мира, Мартин Дрейер рассказывает об основных понятиях объектно-ориентированного программирования — классах, полях, методах и событиях класса. Особенностью книги является то, что повествование о фундаментальных понятиях сочетается с применением самых современных технологий промышленного программирования. Язык программирования C#, среда разработки Visual Studio.Net, база данных SQL Server — все это новые технологии, созданные корпорацией Microsoft.
Фундаментальность и новые технологии — это правильный подход к обучению программированию.
Интересны и предлагаемые примеры. Все начинается, как обычно, с простых иллюстраций.
Однако уже к середине книги появляются «настоящие» приложения, а к концу, где речь идет о работе с базами данных, для их понимания требуются профессиональные знания. Такие примеры демонстрируют возможности того, что можно делать программно.
Трудно, однако, ожидать, что школьник, прочитав эту книгу, сможет написать собственный пример работы с базой данных или с XML-документом, но если у него возникнет желание погрузиться в глубины сказочно интересного мира программирования, цель, которую ставил автор, будет достигнута.
Редактор перевода:
профессор кафедры информатики Тверского государственного университета Владимир Биллиг Введение Эта книга знакомит юного читателя (предполагаемый возраст — 12–16 лет) с объектно-ориентированным программированием, и автор предлагает начать обучение с реальных программ в среде Windows.
Новый язык программирования Microsoft C# (произносится «си-шарп») — очень мощный и в то же время простой в использовании. Он высоко ценится современными ИТ-специалистами и является хорошим выбором для тех, кто только ступает на путь программирования.
Об авторе Мартин Дрейер (Martin Dreyer) — в прошлом школьный учитель, сейчас работает в ЮАР, возглавляет группу разработчиков программного обеспечения. Имеет диплом о высшем образовании по направлению «Естественные науки» и степень бакалавра по направлению «Вычислительная техника и информационные системы».
Часть 1. Первое знакомство Начнем скорее Мне кажется, я знаю, о чем подумали, пролистав первые страницы этой книги:«Хочу написать программу! И как можно скорее! Самое интересное – программировать. Не стоит тратить время на утомительное чтение – хватит слов, пора перейти к делу!»
Честно говоря, мне давно хочется познакомиться с начинающим программистом, который смог бы сопротивляться такому желанию. Ведь как обычно бывает? Представьте: вам купили новый велосипед, и что же вы сделаете? Приметесь читать инструкцию? Конечно, нет. Вскочите на своего коня, понесетесь, расшибете лицо и только потом обнаружите: тормоза-то у этой модели устроены совсем не так, как у других велосипедов!
Но ведь мы хотим добиться успеха? Поэтому давайте договоримся: будем набираться знаний постепенно, с самой первой главы, а когда установите программу на компьютер, попробуйте выполнить некоторые примеры и даже изменить их, если хватит смелости.
Хочу предупредить: первые программы покажутся вам исключительно трудными, как езда вслепую. Ведь даже из-за небольшой ошибки работа зайдет в тупик, а для решения проблемы нужны знания. Вот тогда-то станет понятно: пришло время заняться теорией, как это делают профессионалы. Не унывайте и не сдавайтесь, если что-то не будет получаться. И найдите, пожалуйста, время, чтобы дочитать книгу до конца.
Очень важная часть В программировании, как и во всех других профессиях, наибольшего успеха добиваются люди, любящие свою работу. Если вы получаете удовольствие от того, чем занимаетесь, то непременно захотите изучать новые возможности и двигаться вперед. В таком случае, разрабатывая новые проекты, вы будете набираться знаний и опыта.
Итак, самое главное: наслаждайтесь освоением мира программирования! Для написания программ на языке C# вам понадобятся:
1. Пакет Microsoft.NET Framework 3.5. Это платформа, которая включает все необходимое для создания и запуска программ, которые вы будете писать – библиотеки классов, компоненты и среду, где ваши приложения будут исполняться. Microsoft.NET Framework 3.5 можно бесплатно загрузить на странице http://msdn.microsoft.com/ru-ru/netframework/aa569263.aspx.
2. Среда разработки, для.Net Framework. Среда разработки нужна для того, чтобы сделать процесс работы максимально удобным. Мы рекомендуем Microsoft Visual C# 2008 Express Edition, установочный пакет можно бесплатно загрузить на сайте Майкрософт:
http://www.microsoft.com/rus/express/vcsharp. Если вы установите Visual C# 2008 Express, который уже содержит.NET Framework, выполнять пункт 1 не 3. И наконец, нужно скопировать файлы примеров на диск своего компьютера. Распакуйте архив http://intuit.ru/software/school/cs2kids/examples.zip, сохраните его содержимое в любой папке и запомните, где она расположена – находящиеся в ней файлы вам понадобятся позже.
Дополнительная информация о Microsoft Visual C# Express Edition Программы на C# можно писать и в простом текстовом редакторе (например, в Блокноте) и компилировать (т.е. преобразовывать программный код в набор команд, понятных компьютеру) при помощи так называемого «Компилятора C#», входящего в состав.NET Framework. Однако мы советуем использовать Visual C# Express – упрощенную среду для разработки на языке C#. В ней можно разрабатывать и приложения для Windows, и консольные приложения с текстовым интерфейсом пользователя. Visual C# Express упростит первые шаги в постижении программирования, а после прочтения книги вы сможете двигаться дальше, постепенно усложняя задачи.
Важно понять, что эта книга не предназначена для обучения работы в Visual C# Express Edition.
В Visual C# Express есть множество замечательных функций, например, она умеет автоматически писать код на C#, когда вы перетаскиваете на форму какую-либо кнопку или другой элемент управления. Это замечательная возможность, и ею можно пользоваться, но цель нашей книги – обучить языку C#, причем с самых его основ. Поэтому сначала нужно научиться писать код на C# вручную, только так вы сможете разобраться в устройстве этого языка.
Дополнительная информация о среде разработки Visual C# Express опубликована на сайте компании Майкрософт: http://www.microsoft.com/rus/express/vcsharp.
Создание новой программы (проекта) в Visual C# Express Чтобы запустить Visual C# Express, в меню «Пуск» укажите «Все программы» и затем выберите «Microsoft Visual C# Express Edition». Если на рабочем столе уже есть нужный вам значок (ярлык), просто щелкните по нему.
Для создания нового проекта откройте меню File («Файл»), щелкните New project («Новый проект») и выберите тип проекта. Мы начнем с нескольких консольных приложений, а позднее перейдем к приложениям для Windows.
Попробуем создать новое консольное приложение и нажмем «ОК». Откроется студия разработки с множеством окон. Центральное окно предназначено для программирования, здесь будет показан автоматически созданный код класса Program.cs. Удалите его полностью и наберите текст программы, приведенной ниже. Помните наши договоренности: не скопируйте, а именно наберите – вручную. Разумный человек сумеет справиться с ленью!
using System;
class PleaseSayUra static void Main() Console.WriteLine(“Ура!“);
Console.ReadLine();
Убедитесь, что набранный вами текст в точности соответствует представленному в книге. Затем нажмите кнопку «Выполнить» (или клавишу F5).
Если все сделано без ошибок, откроется окно консоли с текстом «Ура!».
Для завершения программы надо нажать на кнопку «X» в верхнем правом углу окна или на любую клавишу.
Если в коде программы обнаружится ошибка, вы получите предупреждение. Обратите внимание на то, что в языке программирования C# в конце каждого предложения или выражения должна стоять точка с запятой. Попробуем удалить последнюю точку с запятой («;») и затем выполнить программу – на экране появится следующее сообщение В большинстве случаев нужно нажать на кнопку «Нет», и тогда в окне «Список ошибок» вы увидите некоторые сведения, включая указание номера строки, в которой ошибка была найдена. Щелкните дважды на это описание, чтобы перейти к нужной строке и исправить ошибку.
Выполнение примеров программ, прилагаемых к книге Эта книга построена на изучении примеров программ – от самых простых (наподобие программы «Ура», код которой был только что приведен) до сложных, работающих с базами данных.
Каждый пример реализован как отдельный проект. Для удобства все проекты объединены в одно решение (Solution) и находятся в общей папке с именем Examples, которая хранится в архивированном виде Examples.zip на сайте http://intuit.ru/software/school/cs2kids/examples.zip. Скопируйте этот файл на жесткий диск вашего компьютера и разархивируйте ее, чтобы получить папку Examples, где и лежат папки и несколько файлов. Папка с именем databases хранит базы данных, необходимые для некоторых проектов. Папки с именами Example1, …, Example15 содержат отдельные проекты на C# – именно эти примеры обсуждаются в книге. Каждая папка имеет сложную внутреннюю структуру, состоящую из других папок и файлов.
В папке Examples находится центральный для нас файл Examples.sln, где хранится решение с проектами. Запуск любого проекта будем выполнять с его помощью: если щелкнуть по этому файлу, то решение со всеми проектами будет загружено в студию разработки. Теперь можно запустить любой пример. Для этого достаточно:
Выбрать нужный вам проект из тех, что показаны в окне студии: если, скажем, нужен пример с номером 10, выберите проект с именем Example10.
Установить курсор на имени проекта, нажать правую кнопку мыши и в появившемся контекстном меню выбрать пункт «Назначить запускаемым проектом» (Set as StartUp Project).
Запустить проект на выполнение. Это можно сделать разными способами: если нажмете на клавишу F5, проект начнет работать в отладочном режиме, а комбинация клавиш Ctrl+F5 запустит проект без отладки. Другие варианты: выбрать в меню Debug соответствующие пункты или щелкнуть мышью по специальной кнопке «Выполнить».
На рисунке показан внешний вид студии разработки, который формируется в процессе работы с представленными в книге примерами:
Знакомство с понятиями языка C# Во II части книги дается общее описание ключевых понятий. Такое краткое изложение называется «строительным блоком». Рассмотрим пример строительного блока.
Строительный блок: Классы Все программы на языке C# создаются внутри классов. Основная структура класса имеет следующий вид:
Возможно, вы захотите ознакомиться с возможностями Visual C# Express, просмотреть файлы, содержащиеся в разделе «Справка», и попробуете понять, что же собой представляет эта программа.
Совсем скоро вы убедитесь, что для диалога с компьютером одних лишь средств программирования недостаточно — нужно нечто большее.
Поэтому настало время перейти к следующей части книги, чтобы учиться общению с компьютером на языке программирования C#.
Часть 2. Учимся общаться с компьютером Люди и компьютеры Написание программ осложняется тем, что компьютер совсем не похож на людей и «воспитание» у нас разное. Если бы это было не так, то и компьютер, и мы одинаково бы воспринимали окружающий мир и умели бы говорить на одном языке. Тогда нам было бы легче понимать друг друга: достаточно попросить компьютер нарисовать кота — и все.
Вы скажете: «В чем же дело? Давайте научим компьютер понимать нас!». Но эти машины устроены совсем не так, как человеческий мозг, и «видят» мир иначе, поэтому обучить их мышлению, подобному нашему, — непростая задача.
Впрочем, выход есть: надо найти то, что поможет прийти к согласию:
общий язык, который способны понимать как люди, так и компьютеры.
Эта часть книги полностью посвящена изучению способов общения с компьютером. Надо только «развернуть» свое сознание, чтобы увидеть вещи так, как будто вы находитесь в роли компьютера. При этом придется пойти на взаимные уступки: компьютер сможет научиться многому из того, что делаем мы (например, запомнит некоторые слова), но и вы должны будете уяснить некоторые особенности его мира. Попытайтесь забраться в «голову» компьютера и представить, как можно было бы изложить мысли.
Компьютеры не могут догадываться о том, что мы думаем, чего от них хотим и каким образом они могут выполнить наши желания. Остается только мечтать о том дне, когда они будут откликаться на один лишь взгляд и движение бровей в их сторону, но сейчас приходится четко излагать свои идеи и даже давать компьютерам указания, которым они обязаны следовать. Короче говоря, взаимопонимания между людьми и машинами до сих пор нет, и если мы хотим добиться от них помощи, то придется преодолеть эту пропасть.
Итак, давайте ненадолго забудем о компьютерах и представим, что вам крайне необходимо найти общий язык с неким пришельцем. А история такова… К счастью или нет, но что-то произошло во Вселенной, и вы оказались на маленьком пустынном острове посреди океана один на один со странным существом. После отчаянного «Привет, меня зовут Света, а тебя?», вы, в конце концов, решаете дать своему Подступивший голод дает о себе знать. По счастью на высокой пальме висят несколько кокосов, и Алджи мог бы достать их. Вот только как объяснить ему, что надо сделать?
На песке вы рисуете изображение кокосовой пальмы и, указывая на него, произносите лично воспринимает ваши дальнейшие объяснения. Обнаруживается, что у этого создания талант к языкам. До наступления сумерек Алджи овладевает русским.
Волнуясь от осознания собственного успеха, вы решаетесь попросить: «Алджи, пожалуйста, подними меня на плечи, чтобы я могла достать кокосы!»
Он смотрит на вас озадаченно. Затем с таким же видом переводит взгляд на изображение кокосовой пальмы. Потом опять на вас. И снова на рисунок. Бесполезно — он не понимает! Осознав свою ошибку, вы хватаетесь за голову и растерянно показываете на настоящую пальму. Но Алджи по-прежнему не может понять. Оказывается, он понимает только рисунки. Ага! Теперь-то становится ясно, что, хотя Алджи и может использовать ваш язык, он фактически НЕ понимает реальных вещей, о которых вы говорите.
Каким-то образом надо прийти к общей точке зрения. На первый взгляд, все просто:
раз удалось научить языку, то можно обучить и правильному пониманию объектов реального мира. Но и через трое суток кокосы по-прежнему висят на пальме. Уроки оказываются бесполезными, и вы теряете контроль над ситуацией по мере того, как перестаете понимать, в чем же дело.
Вы не знаете, сон это, галлюцинации или видение, но в ярком, туманном свете появляется фигура в белом. Низкий голос подсказывает: «Вот отличный способ восприятия окружающего мира! Только так вы и Знифф12 (вот оно – настоящее имя Алджи!) сможете понять друг друга». Неизвестно сколько времени проходит, пока образы магически проникают в ваш разум, обучая новому способу описания мира. Наконец, успокоившись, вы выбираетесь из этого состояния.
Встрепенувшись, хватаете Алджи за плечи: «Я все поняла, приятель, слушай внимательно то, что я тебе скажу». Алджи с нахмуренным видом вслушивается в вашу речь.
«В окружающем нас мире существуют различные классы объектов — растения, животные, голодные люди, инопланетяне и так далее».
«Сейчас я хотела бы рассказать тебе об объектах, существующих на этом острове. Прежде всего, если ты еще не заметил, меня очень интересует эта кокосовая пальма (между прочим, она входит в класс, называемый «растениями»). Мне интересен и вон тот слон.
Ух, ты! Странно, что я не заметила его раньше». (Вы указываете на каждый объект, о котором говорите.) «Слон входит в класс под названием «животные» и имеет некоторые важные для нас свойства. Во-первых, все животные могут двигаться. Во-вторых, слон очень тяжелый, наверное, тонны две – это нам пригодится. В-третьих, у него скверный характер, что тоже может оказаться полезным».
«Ну, а теперь, Алджи, слушай меня... В окружающем нас мире непрерывно происходят события. Я проголодалась — это событие. Кокосы созревают — и это событие. Иногда мы сами можем вызывать события, чтобы выполнить некоторое действие. У меня есть отличная мысль: давай вызовем событие «беспокойство слона», которое заставит его помочь нам выполнить действие «добывание кокосов».
«Разделим обязанности. Я вызову событие (привлеку к тебе внимание слона), а ты заставишь его достать для нас кокосы, договорились?» При этом Алджи робко смотрит на вас и признается: «Света, я слышу твои слова, но не понимаю, как это сделать». Похлопывая товарища по спине, вы говорите: «Не беспокойся, я никогда не стану просить тебя о чем-либо, сначала не объяснив тебе метода выполнения этого действия. Вот что нужно будет сделать после того, как я скажу: «Достань кокосы»:
Выбеги из-за этого камня и встань рядом с пальмой. Слон немедленно понесется В тот момент, когда он достигнет нарисованной мной на песке линии, беги изо всех сил (поворачивать в разные стороны и бегать взад и вперед не надо).
Слон ударится о пальму и на некоторое время оцепенеет, но силой удара кокосы будут сбиты, и мы позже сможем собрать их.
После этого возвращайся назад и сообщи результат».
Алджи надолго замирает, переваривая задание, потом неожиданно достает суперсовершенное устройство связи, в течение некоторого времени издает звуки, напоминающие верещание модема, и затем снова кладет устройство в карман. Вы спрашиваете: «Что это было, Алджи?». Он отвечает: «Позволь мне перевести, Света...
Существует класс объектов, называемых Икс-знифферами.
Я один из объектов такого класса, но есть и другие.
Все объекты этого класса обладают следующими свойствами:
– name («имя», например, мое имя — Знифф12);
– earShape («формаУха», значение этого свойства — «трубка» — всегда постоянно);
– likeToWatchTV («люблюСмотретьТелевизор», в некоторых случаях это правда, а в Должен признаться, мое появление здесь не случайно. Ты попала в популярное ТВ-шоу «Остаться в живых», а минуту назад я позвонил своему продюсеру и сказал, что меня не удовлетворяет обещанная плата за такое опасное задание. Он собирается немедленно выполнить метод «ОтправитьСпасательнуюГруппу».
На этом история заканчивается. Смысл в том, что вам с Алджи удалось разработать общий способ описания мира: вы используете одни термины — класс, объект, метод, свойство — и одинаково понимаете их значение. Это, наряду с использованием единого языка, дает вам возможность общения.
Теперь представим, что вам нужно объясниться с компьютером. Решение будет аналогичным рассказанной истории, и проблему можно решить путем согласования общего способа восприятия мира, который сможет обеспечивать взаимопонимание человека и машины.
Классы и объекты в языке C# Подход с использованием «классов, объектов, свойств, событий и методов» (о нем и было рассказано в истории) не является единственно возможным. Это только один из способов, который поможет объяснить пришельцу, как устроен окружающий нас мир. Крайне важно договориться о том, что вы будете описывать его при помощи одинаковых образов. Такой взгляд на мир (кстати, он называется «объектно-ориентированным» подходом) стал очень популярным способом описания вещей, и фактически язык C# требует придерживаться именно его.
Итак, изучение языка C# — это изучение способов описания вещей при помощи классов, объектов, событий, методов и т. д.
Если вы хотите, чтобы компьютер выполнил определенные действия, то вам придется сделать следующее:
выучить язык C# и научиться описывать вещи с ориентацией на объекты;
установить на компьютере приложение C# и другие сопутствующие программы. Тогда компьютер сможет понимать язык C# и работать с объектами, описанными в соответствии с объектно-ориентированным подходом.
Вот и все: общее представление о мире и общий язык. Вскоре будете общаться с компьтером, как старые приятели.
Теперь необходимо понять, что собой представляет ориентация на объекты с точки зрения программиста.
Окружающий нас мир можно разделить на различные классы вещей: например, «коты», «дома» или «деревья». Классы можно считать именованными категориями, позволяющими группировать сходные объекты. Надо найти такой способ описания классов, который позволял бы компьютеру оперировать с классами и выполнять действия с их Каждый класс вещей включает нужные нам объекты. Например, к классу «кот» относится мой кот Пушок – он является объектом класса котов. Дом на углу моей улицы не что иное, как объект класса «дом», а дуб, видимый из окна спальни, – объект класса «дерево». Если есть определенный объект, с которым должен работать компьютер, то необходимо создать некоторое описание, представляющее такой объект.
Для объектов характерны различные свойства, которые помогают четко описать объекты. Их можно сравнить с прилагательными в русском языке. Например, моего большого упитанного Пушка можно описать такими свойствами, как рост, вес и т. д.
События — это некоторые особые состояния, в которые может попадать объект. В реальном мире события происходят вокруг нас непрерывно. Например, когда я глажу Пушка, для него наступает приятное событие, которое можно назвать «Нирвана». Если налетает сильный ветер, ломающий ветви уже упоминавшегося здесь дуба, то с деревом происходит событие под названием «Ураган». При возникновении события, как правило, выполняются определенные действия, влияющие на состояние объекта. Действия по обработке события выполняются не самим объектом, а другими объектами, которые могут получать сообщение о возникающих событиях. При работе с компьютерным приложением, где есть видимые объекты, например, компьютерные игры, событиями могут быть «нажатие на кнопку», «нажатие на определенную клавишу» или «щелчок кнопки мыши».
Объект может выполнять действия. Например, кот Пушок лижет свою шерсть — это действие. В компьютерном мире определенные действия выполняются, когда происходят интересные события, например, при нажатии на кнопку выполняется действие «рисуем кота».
Хотите верьте, хотите нет, но компьютер может не иметь представления о том, как надо рисовать кота. В этом случае необходимо дать описание, которое будет ему понятно, — метод рисования кота, это набор пошаговых инструкций, определяющих порядок выполнения конкретных действий.
В последующих разделах мы рассмотрим каждый аспект объектно-ориентированного программирования и приведем более детальное описание. Начинаем учиться программировать на языке C#.
В окружающем нас мире можно выделить различные группы вещей. Назовем их классами.
Вспомним, как создаются классы в школе. Детей определенного возраста или с определенными способностями объединяют в группу и называют ее классом. Такой подход позволяет уравнять их в правах: все будут изучать одни и те же предметы и сдавать одни и те же экзамены.
Но это не означает, что все ученики класса одинаковы, у них всего лишь имеются некоторые общие особенности.
Рассмотрим другой пример: в группе живых организмов можно выделить два класса — «растения» и «животные».
Теперь попробуем научиться выражать свои мысли так, чтобы компьютер смог понять то, что мы пытаемся сказать.
В C# описание класса для компьютера может иметь следующий вид:
class Animal Из этого небольшого отрывка кода компьютер понимает следующее:
мы собираемся изучать класс объектов;
мы назвали этот класс Animal;
описание этого класса будет расположено между фигурными скобками { … }.
Класс «Animal» имеет смысл определить в программе, выводящей на экран изображения животных или сохраняющей интересные факты о них. При решении других задач надо будет описывать другие классы, например, классы MyPhotoProgram или MyGradeCalculator. Нужно понимать, что классы объединяют не только те объекты, которые существуют в реальном мире. Они полезны и при работе с абстрактными объектами.
Строительный блок: Классы Все программы на языке C# представляют собой описание множества классов.
Компьютеру известно слово «class», которое должно быть написано строчными буквами, но имя класса может быть любым и содержать как прописные, так и строчные буквы, причем использование пробелов не допускается.
Немного позже мы расскажем о том, что происходит внутри описания класса (между фигурными скобками). Но сначала рассмотрим объекты.
Каждый класс описывает, как устроены объекты класса. В процессе работы с классом «Animal» могут появиться объекты этого класса:
кот Барсик, принадлежащий вашей тете;
безымянная корова, виденная вами всего один раз;
горилла по кличке Джереми;
Создание объектов Вы уже знаете, как вести разговор с компьютером о классе животных. Возможно, в какой-то момент вам захочется поговорить и об объектах. Например, о том, что «есть одно существо в классе животных, которого зовут Барсиком».
Это можно выразить следующим образом:
Animal Barsik;
Мы написали небольшой отрывок кода, и здесь нужно остановиться и подумать, иначе можно упустить главное. Компьютер понимает следующее: «Этот человек хочет поговорить об объекте в классе Animal и назвать его Barsik. Я не знаю, что такое Barsik, и мне все равно – пусть называет, как хочет».
Теперь дополним приведенный выше код еще одним выражением:
Barsik = new Animal();
Может показаться странным, но нужно сделать именно так, потому что с точки зрения компьютера в этом есть смысл. Подумайте «как машина» и представьте себе следующее:
Первое выражение (Animal Barsik) предупреждает компьютер, что вскоре мы попросим его работать с объектом из класса Animal. Теперь у компьютера появляется возможность проверить свои знания об этом классе. Он просматривает всю программу и ищет нужное описание. Не найдя такого класса, он сообщит вам, что сделать ничего не сможет. Если же отыскать нужное описание удастся, компьютер продолжит выполнение программы, ожидая вашей дальнейшей просьбы совершить некоторое действие с объектом класса Animal по имени Barsik.
Второе выражение (Barsik = new Animal();) напоминает компьютеру: «Помнишь объект Barsik? Теперь мне нужно выполнить с ним действие. Выдели немножко памяти в своей голове, где ты хранил бы данные об этом животном». Компьютер запоминает новый объект класса Animal и понимает, что это объект Barsik, упомянутый ранее. Изучив класс Animal, компьютер кое-что знает о Барсике и держит эту информацию наготове, понимая, что может получить от вас дополнительные сведения об этом объекте.
Теперь рассмотрим все три момента и представим себе, как компьютер «думает» о них.
Заметьте, в первом блоке мы описываем класс объектов в общем, а в блоках 2 и 3 выделяем определенный объект в классе Animal.
//Примечание редактора. По-английски fiddlestick означает «смычок», а fiddlesticks — «вздор, чепуха». Но, как уже говорилось, имя может быть любым, в том числе и «чепушинка».
Строительный блок: Объекты Объекты — это отдельные, четко обозначенные class Animal экземпляры некоторого класса.
Класс дает общее описание объектов, указывает «на что они похожи».
Рассмотрим процесс объявления и создания объектов класса.
Если планируется работать с определенным объектом, необходимо заранее сообщить компьютеру, к какому классу он принадлежит, для того чтобы компьютер проверил свои знания о нужном нам классе. Поэтому сначала указываем имя класса, а затем даем имя объекту.
Этот процесс называется «объявлением объекта».
Затем необходимо попросить компьютер «создать экземпляр» класса.
На основе своих знаний о классе компьютер создаст реальный объект, с которым он сможет выполнять действия.
В нашем примере объект percyThePorcupine становится экземпляром Animal, или можно сказать, что percyThePorcupine — это «объект» типа Animal.
Но в любом случае нам уже точно известно, что мы говорим об определенном объекте класса Animal. Это называется «созданием объекта».
Теперь мы знаем, как рассказать об определенном объекте в классе, но поскольку класс, который мы рассматриваем, достаточно прост (можно сказать, он совсем пустой), то работать с ним неинтересно. Итак, в следующем уроке мы добавим к нему некоторые элементы.
Свойства объектов Если бы я попросил вас перечислить несколько свойств животных, то список мог быть следующим:
Вид животного (Kind of animal).
Количество лап (Number of legs).
Наличие хвоста (Has a tail).
Является ли млекопитающим (Is a mammal).
При рассмотрении свойств этих животных вы можете присвоить значения каждому из них:
Kind of animal = «Cat» («Кот»).
Height = 50 cm (большой котяра!).
Length = 110 cm (это рысь скорее, а не домашняя кошка!).
Color = «Black» (черный).
Has tail = true (истина).
Is mammal = true (истина).
В C# эти свойства называются полями. (Слово «свойства» используется для несколько иной цели, но здесь мы не станем вдаваться в подробности.) Теперь рассмотрим нечто, о чем в реальной жизни беспокоиться не приходится, но в мире компьютеров оказывается очень важным. Обратите внимание: все указанные выше свойства кажутся однородными, однако фактически существуют разные типы полей. Приведем несколько примеров.
Значения полей height, length и number of legs являются числами. Как правило, компьютер использует эти значения для выполнения математических операций.
В задаче с бананами поля можно было бы назвать так: numberOfBananas («количествоБананов»), numberOfPeople («количествоЛюдей») и numberEachOneGets («количествоПолучаемоеКаждым»). Они должны иметь числовой тип, поскольку с их помощью мы выполняем некие математические вычисления.
Примечание. В языке C# имена полей не могут содержать пробелы. Используйте в именах только буквы и числа, причем первой всегда ставится буква.
Поля kindOfAnimal и color относятся к строковому типу. Значением таких полей может быть любой текст. В нашем примере значения задаются словами «cat» и «black», заключенными в кавычки.
Надо отметить, что в строковом поле (в строке) текст может содержать числа. Например, в тексте «Сегодня это уже 17-й крокодил, которого я вижу!» присутствуют буквы, пробелы, числа и знаки препинания, но с числами, находящимися в строке, нельзя выполнять математические операции.
Поле типа hasTail всегда будет принимать значение ИСТИНА или ЛОЖЬ (true/false), точно так же, как любые поля типа ДА или НЕТ («yes/no»). Такие поля относятся к логическому типу.
Каждый «тип» обрабатывается компьютером особым образом, поэтому при определении полей мы должны указывать их тип. В одной программе мы определим поле numberOfLegs как строку, поскольку мы не планируем выполнять математические операции над этим полем, а в другом случае, когда надо будет узнать, сколько конечностей у 500 одинаковых объектов, может потребоваться использование такого поля в качестве числового.
Тип «String» (строка) Для того чтобы попросить компьютер рассматривать некое свойство как строку, состоящую из букв, достаточно просто объявить объект следующим образом:
string kindOfAnimal;
Пока мы не задаем значение в этом поле, а всего лишь сообщаем, с каким типом данных будем работать, и присваиваем полю имя. Поставьте себя на место компьютера и представьте, как бы вы отреагировали, если бы человек написал для вас следующее:
Числовые типы Извещая компьютер о том, что значение поля нужно рассматривать как число, необходимо выбрать один из нескольких числовых типов, известных в языке C#. Наиболее распространенный — integer. Из курса математики вы должны знать, что это не что иное, как целое число, которое может быть отрицательным, положительным или нулем.
То, что значение поля должно быть целым числом, проще всего сообщается так:
int numberOfLegs;
А вот что подумает в этом случае наш цифровой друг:
Тип «Boolean» (логическое значение) Если вам известно, что некоторое поле будет всегда принимать значения «true» («истина») или «false» («ложь») и ничего другого, то использование в C# поля типа «true/false» может оказаться полезным. Это самый простой из всех типов, хотя такие поля носят довольно странное название — булевые (Boolean), по имени математика Джорджа Буля.
Извещая компьютер о том, что поле «hasTail» должно принимать значения «true/false», используйте следующий код:
bool hasTail;
Машина будет думать следующим образом:
Итак, поля представляют собой элементы информации, позволяющие лучше описать объекты в классе. Они всегда имеют определенный тип.
Добавление полей в класс Ранее, когда мы знакомили компьютер с классом животных, то просто дали классу название – Animal, добавили в код фигурные скобки и пообещали рассказать о нем больше, а точнее — сообщить о том, что находится внутри него. Запись выглядела так:
class Animal А теперь мы готовы добавить несколько полей в определение класса.
class Animal string kindOfAnimal;
string name;
int numberOfLegs;
int height;
int length;
string color;
bool hasTail;
bool isMammal;
bool spellingCorrect;
Код должен быть аккуратным и легко читаемым, для чего и создаются отступы полей, показанные выше. Это делается при помощи клавиши TAB на клавиатуре – для одной строки или, выделив сразу несколько строк, для всех сразу.
Поля и объекты Итак, мы объяснили компьютеру, что ВСЕ объекты класса Animal имеют перечисленные выше поля. Теперь давайте попросим его создать экземпляр, представляющий определенный объект класса Animal (как мы делали это в предыдущем разделе), и сообщим компьютеру некоторую информацию об этом объекте, присвоив значения каждому полю.
Animal Barsik;
Barsik = new Animal();
Barsik.kindOfAnimal = “Cat”;
Barsik.name = “Кот Барсик”;
Barsik.numberOfLegs = 4;
Barsik.height = 50;
Barsik.length = 110;
Barsik.color = “Black”;
Barsik.hasTail = true;
Barsik.isMammal = true;
Обратите внимание, что в кавычки (“”) заключается значение только строковых полей. В конце каждого выражения ставится точка с запятой (;), после чего полученная конструкция становится оператором присваивания.
На данном этапе стоит упомянуть, что выбранное нами имя объекта Barsik не имеет никакого значения для компьютера, который будет работать с объектом, даже если мы заменим имя Barsik на X или любое другое:
Animal X;
X = new Animal();
X.kindOfAnimal = “Cat”;
X.height = 50;
X.length = 110;
X.color = “Black”;
X.hasTail = true;
X.isMammal = true;
Примечание редактора. То, что компьютер способен обрабатывать любые имена (проблемы не составит даже кот, которого зовут ГЩ12я), не означает, что объекты можно именовать как попало. Имя многое говорит человеку, поэтому крайне важно давать объектам содержательные имена, позволяющие лучше понимать смысл программы.
Еще одно важное замечание. Каждый объект можно рассматривать как коробочку, внутри которой находятся ящички (поля). У двух объектов одного класса коробочки одинаковые, но значения, хранящиеся в ящичках (полях), — разные. Например, два объекта Миша и Гриша имеют поле «Рост», но Миша высокий, а Гриша маленького роста.
Строительный блок: Поля Обычно в классе присутствует одно поле или несколько полей, которые позволяют описывать определенные черты объектов этого класса.
Поля всегда имеют определенный тип. Допустимых типов очень много, вот описание наиболее распространенных из них:
string Строковый тип данных предполагает, «Petr» («Петя») что значением поля может быть слово «Eight-legged Octopus» («Восьминогий или предложение, состоящее из символов Осьминог») алфавита, цифр, знаков препинания и т.д. «Girls are too clever to fall out of their int Числовой тип данных предполагает, что bool Логический тип данных предполагает, что True — истина (true), либо ложью (false). Название типа – сокращение от слова «boolean».
При определении поля в программе необходимо указать его тип и имя:
string lastname;
Обозначение типа должно быть известно компьютеру. Указанные выше основные типы пишутся строчными буквами, однако некоторые могут содержать и прописные буквы.
Давая имя полю, можно использовать любое слово, например, VsegdaNacheku – здесь сочетаются заглавные и строчные буквы. Обратите внимание: пробелы ставить нельзя.
При работе с определенным объектом полям присваиваются значения, которые помогают описывать объект. Если, например, у нас есть объект с именем schoolKid (Школьник), то его полям можно было бы присвоить следующие значения:
schoolKid.firstName = “Petr”;
schoolKid.age = 13;
Имя объекта и имя поля разделяются точкой (.).
Итак, schoolKid.firstName = “Petr” означает следующее: «Petr становится значением поля firstName (Имя) объекта schoolKid».
Закрытые, защищенные и открытые поля На первом этапе изучения языка C# этот раздел не столь важен, но в дальнейшем вам могут встречаться слова private, protected и public. Давайте обсудим их смысл.
class Animal string kindOfAnimal;
string name;
int numberOfLegs;
int height;
int length;
string color;
bool hasTail;
bool isMammal;
bool spellingCorrect;
class MyTestClass Animal myAnimal;
Объекты одного класса могут быть полями в другом классе. Например, в классе MyTestClass появится поле myAnimal, принадлежащее классу Animal.
При объявлении полей так, как показано выше, мы можем решить, должны ли другие классы иметь к ним доступ. Иногда очень важно делать поля закрытыми (private) — для того, например, чтобы другой класс не помещал неверные значения в поля и не нарушал работу программы. Использование полей private, protected и public определяет степень защиты объектов класса.
На рисунке изображены дети, живущие в одной семье. Обратите внимание на то, как обеспечивается безопасность каждоо из них. Малютка Света закрыта (private) в комнате — ее не выпускают из дома, и она имеет наиболее высокий уровень защиты. С ней могут общаться люди, обладающие наибольшим доверием. Борису разрешается находиться как на переднем, так и на заднем дворе, но он по-прежнему в некоторой степени защищен (protected). Толя, старший ребенок, является открытым (public) для других, и любой желающий может общаться с ним.
Итак, в начало описания поля мы можем добавить еще одно слово:
class Animal public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
Вы можете поинтересоваться: а что произойдет, если мы не станем включать эти слова? В таком случае по умолчанию задается значение private и компьютер воспринимает код, как если бы в начале объявления было написано слово private. Поэтому в последнем примере поле hasTail автоматически становится закрытым (private).
Давайте уточним значения этих слов:
Private – «объекты только этого класса могут обращаться к данному полю».
Public – «объекты любого класса могут обращаться к этому полю».
Protected – «только объекты классов-наследников могут обращаться к полю». Если построен класс Animal, то другой класс, например, класс Mammal (Млекопитающее), может объявить себя наследником класса Animal.
Следующие примеры двух классов демонстрируют описанный принцип полей public и private. Поля типа protected мы оставим без обсуждения, а сведения о них можно найти в справке Visual C# Express.
Как и ранее, сначала мы определяем несколько закрытых и открытых полей в классе Animal и затем пытаемся обратиться к ним из класса Zoo.
class Animal public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
class Zoo Animal a = new Animal ();
// Следующая строка будет выполнена успешно, поскольку классу “Zoo” // разрешено обращаться к открытым полям в классе “Animal” a.kindOfAnimal = “Kangaroo”;
// Обе следующие строки НЕ будут выполнены, поскольку классу “Zoo” // не разрешено обращаться к закрытым или защищенным полям a.isMammal = false; // Попытка обращения к защищенному методу a.spellingCorrect = true; // Попытка обращения к закрытому методу Методы класса Если бы классы позволяли только описывать свойства объектов, то пользы от них было бы мало. Безусловно, мы хотим, чтобы объекты могли выполнять какие-то действия:
выводили слова на экран;
копировали данные с веб-узла;
регулировали яркость фотографии;
…и выполняли еще тысячи операций.
А теперь вспомните уроки, на которых вас учили сложению чисел. Вероятней всего, сначала учитель объяснял, КАК это делается, описывая, возможно, каждый шаг. Другими словами, в первую очередь рассматривался МЕТОД решения задачи определенного типа, то есть набор пошаговых инструкций, поясняющих порядок выполнения действий.
А следуя уже известному вам методу решения задач, вы справитесь с любыми похожими задачами,.
Подобным образом, для того чтобы компьютер выполнял нужные нам действия, надо написать код, разъясняющий порядок их выполнения, то есть описать метод, который будет использоваться для выполнения необходимых действий, а затем применять этот метод при решении задачи подобного типа.
В языке C# метод позволяет описать порядок выполнения определенных действий. Описание метода называется программным кодом или просто кодом. В нужный момент метод может быть вызван. Компьютер читает код метода и выполняет именно то, что предписано.
Вот пример простейшего метода:
void SayHello() Этот метод ничего не делает, потому что между фигурными скобками. Давайте зададим здесь какое-нибудь действие.
void SayHello() Console.WriteLine(“Hello”);
(Придадим коду аккуратный вид и при помощи клавиши TAB создадим в методе отступы.) Если вызвать этот метод, то на экран будет выведено слово «Hello». Задача не слишком сложная, поэтому и метод довольно прост.
Что означает VOID?
Странное слово void в приведенном выше примере может несколько озадачить, и вы можете поинтересоваться, зачем вообще его использовали. Вкратце остановимся на этом. Вспомните фильм о космических путешествиях: представьте безграничное пустое пространство во вселенной. Void означает пустоту, «ничего».
Использование слова void перед именем метода означает, что, когда завершается выполнение метода, возвращается пустое значение, то есть по завершении определенных действий, которые выполняет метод, он никаких значений не возвращает. В приведенном выше примере метода «SayHello» нас это вполне устраивает, поскольку после написания слова «Hello» возвращать ничего не нужно. Все необходимое было сделано во время работы метода.
Вы сможете лучше понять смысл этого слова, когда мы будем рассматривать случаи, где метод должен будет возвращать некоторый результат. Подобный пример появится немного позже.
Вызов метода Написав приведенный выше код, мы объяснили компьютеру, КАК выводить приветствие на экран, но не сказали, КОГДА ему нужно воспользоваться приобретенным умением.
Это выглядит так, как если бы на уроке вам рассказали, как складывать числа, после чего вы записали метод, но решить задачку или пример вас не попросили.
Чтобы заставить компьютер выполнить действие, нужно вызвать метод. Для этого надо просто написать имя метода и поставить рядом круглые скобки:
SayHello();
Когда компьютер встречает эту строку, он понимает, что нужно выполнить команду, но встроенного метода с таким именем у компьютера нет, поэтому он лихорадочно начинает искать написанный вами метод с именем «SayHello». Если найти такой метод удается, он быстро выполняет все предписания, записанные в коде метода.
Затем возвращается к самому началу и, довольный успехом, получает вашу благодарность.
Строительный блок: Объявление и вызов метода Чаще всего в классе присутствует один или несколько методов. Каждый из них выполняет определенное действие.
Методами они называются потому, что именно в них описывается метод выполнения действий – пошаговые инструкции, задающие порядок выполнения операций.
Строка, начинающаяся с двух символов «слеш» (//), называется комментарием. Комментарии только поясняют код, но не влияют на выполнение программы.
Операция «+» определена над строками. Она называется сцеплением строк, или конкатенацией. Результатом операции является приписывание второй строки в конец первой.
Как уже говорилось, объекты класса Person могут Person Petr;
объявляться и создаваться в методах другого класса.
Когда встречается вызов метода ShowFullName, компьютер Petr.lastName = “Ivanov”;
находит в классе Person метод с таким именем и – шаг Petr.ShowFullName();
за шагом – выполняет описанные в нем действия.
Как выполняется метод? Параметры метода В предыдущем разделе мы познакомились с методами вкратце, но о них можно рассказать гораздо больше. Теперь рассмотрим более подробно, как передавать методу значения и получать значения, созданные при работе метода.
Предположим, вам потребовалось, чтобы компьютер вывел на экран следующий текст:
Hello Jo Hello Sam Hello You Один из возможных способов — написать отдельный метод для каждого случая:
void WriteHelloJo() Console.WriteLine(“Hello Jo”);
void WriteHelloSam() Console.WriteLine(“Hello Sam”);
void WriteHelloYou() Console.WriteLine(“Hello You”);
Затем необходимо вызвать их следующим образом:
WriteHelloJo();
WriteHelloSam();
WriteHelloYou();
Но ведь все три метода очень похожи. А что если написать один метод WriteHello, дополнив его соответствующими параметрами, и при каждом вызове просто передавать значение параметра, отличающее один вызов от другого?
Вот как это можно сделать:
void WriteHello(string someName) Console.WriteLine(“Hello “ + someName);
и затем вызвать метод следующим образом:
WriteHello(“Jo”);
WriteHello(“Sam”);
WriteHello(“You”);
Как видим, код позволяет сэкономить и занимаемое пространство, и затраченные усилия.
Всегда старайтесь делать код как можно более кратким – чем короче программа, тем умнее программист.
//Примечание редактора. Умный программист пишет не только короткий, но и понятный код.
Хороший код всегда содержит комментарии умного программиста.
Напишем метод подобным «умным» образом:
void WriteHello(string someName) Console.WriteLine(“Hello “ + someName);
Фактически мы говорим: «Каждый раз при вызове этого метода я буду подставлять строку символов с каким-либо именем. Любая подставляемая строка должна выводиться после слова «Hello».
Код в скобках (string someName) называется параметром. Параметр позволяет подставлять значение в метод при его вызове.
Когда вас обучали сложению, учитель не рассказывал о сложении всех существующих пар чисел, он просто научил методу и затем задавал разные задачи: «Сложите 2 и 5, а теперь 7 и 3».
Это похоже на то, как если бы вам излагали метод сложения чисел, используя параметры: неважно, какие значения у параметров, — зная метод, всегда можно найти ответ для заданных значений.
Компьютеру все равно, какое имя вы присвоите параметру, важно, чтобы оно было единым при использовании во всем методе. Например, следующий код будет выполнен правильно:
void WriteHello(string x) Console.WriteLine(“Hello “ + x);
А этот с ошибкой:
void WriteHello(string someName) Console.WriteLine(“Hello “ + someBodysName);
Вы заметили: параметры someName и someBodysName отличаются — наш «электронный друг»
не разберется в этой путанице и «разгневается».
Кроме того, в методе можно использовать не один параметр, а несколько, но нужно обязательно разделить их запятыми:
void WriteHello(string firstName, string lastName) Console.WriteLine(“Hello “ + firstName + “ “ + lastName);
А при вызове метода необходимо подставить правильное количество значений:
WriteHello(“Petr”, “Ivanov”);
В данном случае на экран будет выведен текст «Hello Petr Ivanov».
Ошибки в задании типов параметров Представьте, что когда вы впервые изучали сложение чисел, учитель неожиданно задал вам такую задачу: «Сложите число 5 и цветок».
Как бы вы поступили? Наверное, ответили бы, что цветок — это не число, и выполнить сложение невозможно. Правильно.
Подобным же образом компьютеру не понравится, если вы укажете значение неверного типа. Такая ошибка часто встречается у программистов. Поэтому если что-то не получается, вернитесь к началу и убедитесь, что значения, указанные вами при вызове метода, имеют тип, соответствующий тому, который определен в самом методе.
Строительный блок: Параметры Чтобы в методе выбиралось нужное значение, необходимо указать соответствующие параметры.
Каждый раз при вызове метода мы должны убедиться, что подставляем правильный тип значений в параметры.
В приведенном примере мы подставляем два целых числа, так как параметры метода «LuckyNumber» были определе- Person Petr;
ны как целые числа.
//Примечание редактора. Внимательный читатель спросит: «Складывая строку с числом при вызове метода Console.WriteLine, не делаем ли мы ту же ошибку, как в случае сложения цветка с числом?». Здесь мы полагаемся на то, что компьютер (точнее, компилятор языка C#) умеет справляться с этим – сначала он автоматически преобразовывает число в строку и только потом выполняет операцию сложения — сцепление строк.
Приводимые до сих пор методы были void-методами. Они выводили некий текст на экран и затем возвращались назад к месту их вызова, как бы говоря: «Свое дело я сделал и вернулся в исходную точку». Однако иногда необходимо вернуть некоторое значение в точку вызова метода.
В этих случаях следует написать метод, который будет возвращать значение, отличное от void.
Приведем пример. Напишем метод, который будет выполнять поиск количества конечностей указанного животного и затем отправлять полученное число туда, откуда этот метод был вызван.
Следует помнить, что с помощью метода мы показываем компьютеру, КАК выполнять определенное действие. Сначала я напишу то, чего хочу добиться от него, на русском языке, а затем на C#:
если животное, о котором мы говорим, — слон, то number of legs = 4;
иначе, если животное, о котором мы говорим, — индейка, то number of legs = 2;
иначе, если животное, о котором мы говорим, — устрица, то number of legs = 1;
иначе, если мы говорим о каких-либо других животных, то number of legs = 0.
int NumberOfLegs(string animalName) if (animalName == “слон”) //Если название животного — слон // Возвращаемое значение else if (animalName == “индейка”) //Иначе, если животное — индейка // Возвращаемое значение else if (animalName == “устрица”)//Иначе, если животное — устрица // Возвращаемое значение return 1;
else //Иначе (при всех других условиях) // Возвращаемое значение Теперь мы можем вызвать метод. Давайте сделаем это дважды:
int i;
//Переменная “i” будет хранить значение числа конечностей.
i = NumberOfLegs(“индейка”);
//Теперь i = 2, получив значение, возвращенное методом NumberOfLegs Console.WriteLine(“У индейки конечностей – “ + i);
i = NumberOfLegs(“обезьяна”);
//Теперь i = 0. Догадайтесь, почему!
Console.WriteLine(“У обезьяны конечностей – “ + i);
На экран будет выведен текст: «У индейки конечностей — 2», «У обезьяны конечностей — 0». Итак, метод возвращает значение, которое можно принять в точке его вызова.
Мы определили метод именно так:
int NumberOfLegs(string animalName) void NumberOfLegs(string animalName)...
string NumberOfLegs(string animalName)...
Дело в том, что нам необходимо, чтобы в данном случае метод возвращал целое число — не «пустое» значение (void), не строку букв, а именно целое число. А для работы с целыми числами используется тип данных Integer, или int в сокращенном варианте.
При написании метода мы всегда указываем тип данных, возвращаемых этим методом. Если возвращать значение не надо, используется void – для возврата пустого значения.
void JustWriteSomething(string someThing) Console.WriteLine(someThing);
И наконец: возможно, вы догадались, что слово return возвращает значение. Когда компьютер встречает это слово, происходит выход из метода и возврат запрашиваемого значения.
Строительный блок: Возвращаемые значения Иногда необходимо получить значение из метода. В таком случае вместо указания типа void, сообщающего, что «никакого значения int LuckyNumber(int numberOfTeeth, возвращено не будет», мы указываем определенный тип данных, возвращаемых методом.
Возвращаемые значения автоматически стано- Person Anna;
вятся доступными в любом месте, где мы вызы- Anna = new Person();
ваем метод.
Например, используя возвращенное значение, мы могли бы сначала сохранить ответ в переменной части выражения и затем использовать значение переменной в отдельном выражении.
Или мы могли бы вызвать метод непосредствен- Console.WriteLine(«Счастливое число но в выражении WriteLine. Анны:» + Anna.LuckyNumber(24, 14));
Доступ к методам, аналогично доступу к полям класса, регулируется с помощью ключевых слов. По умолчанию все методы будут рассматриваться как private (закрытые), то есть они применяются только внутри своего класса. Чтобы разрешить их использование для других классов, можно добавить слово public в начало объявления метода.
public void JustWriteSomething(string someThing) Console.WriteLine(someThing);
В реальном мире людям запрещается входить в некоторые помещения без специального разрешения. Например, в ресторанах только повара и официанты могут проходить на кухню – это закрытая зона. В то же время обеденный зал предназначен для свободного доступа, и в нем могут находиться любые лица. Подобным же образом некоторый код закрыт для других классов.
Мы уже рассматривали пример с закрытыми и открытыми полями. Дополним его: введем закрытые (private) и открытые (public) методы в класс Animal и затем пытаемся обратиться к ним из класса.
class Animal public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
// Открытый метод, получающий информацию о том, чем питается животное public string GetFoodInfo() // Представим, что здесь расположен код, выполняющий поиск по базе данных // Закрытый метод для проверки правильности написания вида животного private void SpellingCorrect() // Представим, что здесь расположен код для проверки правописания // Защищенный метод, определяет существование данного вида животного protected bool IsValidAnimalType() //код для проверки существующих видов животных class Zoo Animal a = new Animal ();
a.name = “Kangaroo”;
bool animalExists;
// Следующий код будет выполнен успешно, поскольку классу “Zoo” разрешено // обращаться к открытым методам в классе “Animal” food = a.GetFoodInfo(); // Вызов открытого метода // Обе следующие строки НЕ будут выполнены, поскольку классу “Zoo” // не разрешено обращаться к закрытым или защищенным методам a.spellingCorrect(); // Попытка вызова закрытого метода animalExists = a.IsValidAnimalType(); // Попытка вызова защищенного метода Очень часто встречаются классы с особым типом метода, называемым «конструктором». С точки зрения сиснтаксиса (правил языка) его особенность состоит в том, что имя метода-конструктора совпадает с именем класса и в объявление конструктора не включается тип возвращаемого значения.
Содержательная специфика связана с предназначением конструктора — он нужен для создания (конструирования) объекта. Использование этого метода в классах помогает приобрести хороший практический опыт.
//Примечание редактора. Классов без конструктора не бывает, поскольку объект класса можно создать только путем вызова конструктора класса. Даже если программист не добавит в класс конструктор, это будет сделано по умолчанию, но параметров такой конструктор не имеет. Полезно иметь в классе конструктор с параметрами, роль которых уже пояснялась.
Подобных конструкторов может быть несколько.
class Person string firstName;
string lastName;
// Метод-конструктор для класса Person public Person() firstName = “Johnny”;
lastName = “Rocket”;
Метод-конструктор вызывается по-особому: при каждом создании экземпляра класса с помощью конструкции new.
Напоминание:
Под «экземпляром класса» мы понимаем определенный объект класса. Например, в одном из предыдущих разделов мы выделили «Гориллу Джереми» как определенный объект, или экземпляр класса Animal.
Итак, если мы выполним следующий код:
Person p = new Person();
Console.WriteLine(p.lastName);
то в результате на экране появится слово «Rocket». Написав конструкцию new Person(), мы тем самым дали указание компьютеру вызвать конструктор класса Person для создания нового объЧасть екта этого класса. Он будет связан с переменной p, у которой задано значение «Rocket» для поля lastName.
Приведем аналогичный пример из реальной жизни. В некоторых странах новорожденного регистрируют, согласно закону, еще в родильном доме, чтобы он как можно скорее стал членом общества и получил все гражданские права.
Это действие можно сравнить с методом-конструктором, выполняемым для класса. Прежде чем новый экземпляр класса сможет что-либо сделать, выполняется метод-конструктор. В него можно включить любые планируемые к выполнению действия, прежде чем объект будет считаться «готовым к жизни».
Конструкторы с параметрами В конструктор можно включить параметры. Приведем пример класса с двумя различными конструкторами:
class Person string firstName;
string lastName;
// Первый метод-конструктор public Person() firstName = “Johnny”;
lastName = “Rocket”;
// Второй метод-конструктор public Person(string f, string l) Таким образом, мы получили два разных способа конструирования объекта.
Например, этот:
Person p = new Person();
В таком случае в поле p.lastName будет автоматически подставлено значение «Rocket».
Person p = new Person(“Petr”, “Ivanov”);
Тогда в поле p.lastName будет подставлено значение «Ivanov».
Слово this относится к объекту, который мы создаем, то есть фактически указывается: «подставлять в поле имени и фамилии этого объекта любые значения, передаваемые методу-конструктору».
//Примечание редактора. В данном случае слово this можно добавить и в первый конструктор – для уточнения имени полей. Ничего не изменится, если во втором конструкторе имена полей будут указываться без this. Но иногда такое уточнение необходимо. Например, если во втором конструкторе имя параметра задавать не одной буквой f, а именем firstName, отражающим суть параметра, то без уточнения this в имени поля не обойтись, иначе компьютер запутается, не понимая, где имя поля, а где имя параметра метода.
События В реальном мире события происходят непрерывно, причем некоторые от нас совсем не зависят. Например, восход и закат солнца (хотел бы я посмотреть, как вы пытаетесь заставить солнце вставать и садиться). Другие события мы вызываем сами: скажем, заставляем громкоговоритель издавать звуки.
Рассмотрим несколько событий, которые часто встречаются в мире компьютеров:
нажатие на кнопку, изображенную на экране монитора;
истечение времени таймера;
нажатие клавиши на клавиатуре.
Очевидно, что, нажав на кнопку, мы хотим заставить компьютер выполнить определенное действие. (Если нет – зачем вообще ее трогать?) Но компьютер ждет не только подтверждения, что нажатие этой кнопки имеет для вас какое-то значение, но и указания на действие, которое нужно выполнить.
Рассмотрим подробнее этот пример, поскольку нажатие на кнопку, возможно, является наиболее распространенным событием, и детально разберем порядок работы. Допустим, в вашей программе есть объект — кнопка с именем mrButton, на которой написано «Нажми меня».
По ходу обсуждения попробуйте все делать сами. Для начала:
Запустите Visual C# Express.
Создайте новый проект приложения Windows: в меню File («Файл») выберите Create project («Создать проект») и затем тип проекта Windows Application («Приложение В Visual C# Express откроется несколько файлов, где содержится «скелет» кода программы.
В окне обозревателя решений справа (в списке всех файлов) удалите файл с именем Дважды щелкните имя файла Program.cs и удалите весь автоматически вставленный Чтобы создать программу с экземпляром кнопки, наберите следующий код в окне Program.cs так, как показано ниже (написание слов курсивом или жирным шрифтом можно не учитывать.
using System;
using System.Windows.Forms;
class MyButtonClass: Form private Button mrButton;
// Метод-конструктор public MyButtonClass() mrButton = new Button();
mrButton.Text = “Нажми меня”;
this.Controls.Add(mrButton);
// Основной метод static void Main() Application.Run(new MyButtonClass());
Выполните программу при помощи клавиши F5 (или щелкните по зеленой кнопке «Выполнить»). Если возникнут сообщения об ошибках, тщательно проверьте, нет ли опечаток в коде.
Если программа будет выполнена успешно, вы увидите форму с кнопкой «Нажми меня». Пока при нажатии на кнопку никаких действий происходить не будет. Конечно, вы ожидали другого результата, но все еще впереди.
Событие нажатия кнопки. Указание действия в случае события Теперь мы должны задать метод, выполняющий действие при нажатии на кнопку. Такие методы называются обработчиками событий, поскольку они именно «обрабатывают» событие. В приведенном ниже примере выделенный маркером код обработчика события просто изменяет надпись на кнопке, поэтому он совсем короткий:
using System;
using System.Windows.Forms;
class MyButtonClass: Form private Button mrButton;
// Метод-конструктор public MyButtonClass() mrButton = new Button();
mrButton.Text = “Нажми меня!”;
this.Controls.Add(mrButton);
// Основной метод static void Main() Application.Run(new MyButtonClass());
// Метод-обработчик событий void MyButtonClickEventHandler(object sender, EventArgs e) mrButton.Text = “Вы нажали меня!”;
Ваша программа еще выполняется?
Остановите ее (нажмите на кнопку X в верхнем правом углу окна, в котором открыта Добавьте в программу выделенный код и нажмите на клавишу F5 для выполнения измененной программы.
Попробуйте теперь щелкнуть по кнопке «Нажми меня». И теперь ничего не происходит?!
Поскольку вы уже прочитали те страницы, где мы говорили про методы, то должны узнать основную структуру приведенного выше метода. Слово void означает, что по его завершении ничего не возвращается. Мы назвали этот метод MyButtonClickEventHandler.
Возможно, то, что вы видите, кажется немного странным. Вы понимаете, что в скобках присутствуют два параметра, но почему у них такие необычные типы (object sender, EventArgs e)? К сожалению, с методами обработчиков событий нельзя использовать собственные типы параметров. Когда у кнопки возникает событие «Click», она посылает сообщение о нем операционной системе, а та находит и вызывает соответствующий обработчик события. При вызове такого метода система сама определяет типы параметров и передает обработчику их значения. Это факт, с которым мы ничего поделать не можем.
Поэтому придется просто смириться и всегда использовать ожидаемые типы параметров с обработчиком событий. Очень часто подставляемые параметры имеют тип object и EventArgs.
В приведенном выше примере мы выбрали имена параметров sender и e, но могли бы выбрать любые другие — для компьютера важны имена типов этих параметров. Например, следующий код будет работать точно так же, как и код, рассмотренный в предыдущем примере. Можете проверить это сами, изменив имена параметров в вашей программе на x и y.
//Примечание редактора. Ничего удивительного: эти параметры вообще не используются в тексте обработчика события. Но в ряде случаев они полезны. Например, при работе с мышкой обработчику события могут быть переданы координаты объекта, на котором нажата кнопка мыши.
void MyButtonClickEventHandler(object x, EventArgs y) mrButton.Text = “Вы нажали меня!”;
В первом параметре обычно содержится некоторая информация об объекте, который инициировал событие. Второй параметр относится к данным о самом событии.
Очень важно знать следующее: система всегда подставляет некоторые значения в эти два параметра, но зачастую необходимости в их использовании нет — они отправляются в метод обработчика событий «на всякий случай».
Подключение метода обработчика событий к событию Вы удивляетесь, почему ничего не происходит при нажатии на кнопку? Дело в том, что указанный метод вызывается только тогда, когда мы свяжем с ним событие нажатия на кнопку, укаУчимся общаться с компьютером зав в программе: при нажатии на кнопку необходимо перейти к определенному обработчику событий.
Когда в программе используются разные кнопки и несколько обработчиков событий, без такого уточнения не обойтись,. так как компьютер должен знать, какой именно метод следует выполнять при нажатии на определенную кнопку.
Код для связывания события объекта с методом обработчика события выглядит тоже несколько странно. Мы опять выделим его маркером.
using System;
using System.Windows.Forms;
class MyButtonClass : Form private Button mrButton;
// Метод-конструктор public MyButtonClass() mrButton = new Button();
mrButton.Text = “Нажми меня”;
mrButton.Click += new System.EventHandler(MyButtonClickEventHandler);
this.Controls.Add(mrButton);
// Основной метод static void Main() Application.Run(new MyButtonClass());
// Метод-обработчик событий void MyButtonClickEventHandler(object sender, EventArgs e) mrButton.Text = “Вы нажали меня!”;
С компьютерного языка это можно перевести следующим образом:
«Путем нажатия на кнопку mrButton надо связать событие Click с методом обработчика событий, который называется MyButtonClickEventHandler».
При нажатии на кнопку приведенная выше строка кода позволяет системе вызвать метод обработчика событий, после его выполнения надпись на кнопке меняется на «Вы нажали меня!».
Чтобы использовать этот код, остановите свою программу, добавьте в нее выделенный код и нажмите клавишу F5 для выполнения программы. Нажмите на кнопку, и надпись на ней изменится. Рабочую программу — пример события нажатия на кнопку — можно найти в папке примеров, прилагаемых к книге (Проект Example5).
//Примечание редактора. Программа работает, но можно немного улучшить ее внешний вид.
Сейчас положение кнопки на форме и ее размеры установлены по умолчанию. Для изменения этих параметров добавьте в конструктор класса строчки, выделенные маркером, и снова запустите программу.
public MyButtonClass() mrButton = new Button();
mrButton.Text = “Нажми меня”;
mrButton.Height = 50;
mrButton.Click += new System.EventHandler(MyButtonClickEventHandler);
this.Controls.Add(mrButton);
Теперь мы попробуем описать основную структуру метода обработчика событий мыши. Вероятно, в этом случае вы захотите использовать информацию, подставляемую в параметр MouseEventArgs, хотя бы для того, чтобы выяснить, какая из кнопок мыши нажимается.
public void TheMouseIsDown(object sender, MouseEventArgs e) if (e.Button = MouseButtons.Left) this.Text = “Нажата левая кнопка мыши”;
Далее показано, как связать событие с методом. В переводе с компьютерного в тексте написано следующее: «Если при выполнении этой программы нажимается кнопка мыши, надо перейти к методу TheMouseIsDown», которому известно, как следует обрабатывать события мыши:
this.MouseDown += new MouseEventHandler(TheMouseIsDown);
Можно внести некоторые улучшения, чтобы при запуске следующего обработчика код, содержащийся в нем, делал окно более широким или узким в зависимости от нажимаемой кнопки.
public void TheMouseWasClicked(object sender, MouseEventArgs e) // При нажатии левой кнопки if (e.Button == MouseButtons.Left) // Расширение текущего окна this.Width = this.Width + 100;
else if (e.Button == MouseButtons.Right) // Сужение текущего окна this.Width = this.Width – 100;
Другой обработчик событий позволяет обнаружить перемещение мыши и рисовать окружность в том месте, где находится курсор:
public void TheMouseMoved(object sender, MouseEventArgs e) // Подготовка области рисования System.Drawing.Graphics g = this.CreateGraphics();
// Использование красной ручки System.Drawing.Pen redPen = new System.Drawing.Pen(Color.Red, 3);
// Рисуем окружность как эллипс с равными осями.
// Окружность рисуется в охватывающем ее квадрате.
// Координаты X и Y левого верхнего угла квадрата // определяются координатами текущего положения мыши.
g.DrawEllipse(redPen, e.X, e.Y, 40, 40);
// Очистка g.Dispose();
На снимке экрана показано, как это выглядит при перемещении мыши:
Пространства имен и почтовая служба В мире существуют сотни, а может быть, и тысячи, улиц, названных именем А.С. Пушкина. Но если на конверте указана одна из них, то как письмо находит своего получателя? Естественно, адрес состоит не только из улицы. Мы, по меньшей мере, добавляем название страны и города.
Очевидно, если мы укажем адрес на конверте:
то почта не распознает, где эта улица и где этот дом.
Можно написать так:
улица Пушкина, 17, г. Москва;
улица Пушкина, 82, г. Алма-Ата Так-то лучше, а если существуют два города с одинаковым названием? Например, город Москва есть в США! Поэтому для надежности добавим еще и название страны:
улица Пушкина, 17, г. Москва, Российская Федерация;
улица Пушкина, 82, г. Алма-Ата, Республика Казахстан.
В России адрес принято писать так:
Российская Федерация, г. Москва, улица Пушкина, 17;
Республика Казахстан, г. Алма-Ата, улица Пушкина, 82.
Теперь письмо обязательно дойдет до адресата. Например, второе письмо доставят самолетом в Республику Казахстан, из аэропорта его перевезут на почтамт города Алма-Аты, а потом почтальон пойдет на улицу Пушкина и найдет дом под номером 82.
Формат (Республика Казахстан, г. Алма-Ата, ул. Пушкина) можно считать «пространством имен» для отправки писем.
Пространства имен и программный код Какое же отношение все это имеет к программированию?
Предположим, разработчиками корпорации Microsoft написан класс «Point», используемый для рисования фигуры в определенной точке, но и вы создали класс с именем «Point», например, для загрузки фотографии человека, указывающего на что-либо.
//Примечание редактора. Слово Point в английском языке многозначное и означает как «точку», так и глагол «указывать».
Очевидно, что оба класса выполняют абсолютно разные действия, но и тот и другой можно назвать Point. С каким же из них будет работать программа?
Безусловно, имеет смысл использовать разные имена. В среде.NET для этого можно задействовать различные «пространства имен». Например, так:
Microsoft.Drawing.Point Anna.PictureStuff.Point Имена классов сохранены (Point), но пространства имен перед именами класса позволяют четко видеть, в каком из них находится класс. И теперь, если мне нужно использовать класс Point из пространства Anna, я могу создать объект Point при помощи следующего метода-конструктора:
Anna.PictureStuff.Point annaPoint = new Anna.PictureStuff.Point();
Для работы с классом Point от Microsoft подойдет следующий код:
Microsoft.Drawing.Point microsoftPoint = new Microsoft.Drawing.Point();
Несмотря на то что оба моих объекта принадлежат классу Point, они относятся к разным классам и выполняют разные действия.
Как создать пространство имен и поместить в него собственный класс Разместить собственный класс в пространстве имен очень просто. Раньше мы давали описание класса следующим образом:
class Animal...
Теперь создайте пространство имен и внутри него опишите класс:
namespace Anna class Animal Или, если хотите, сделайте так:
namespace Anna.FunStuff class Animal Пространства имен могут быть вложенными друг в друга. Тогда их имена разделяются точками. В последнем примере класс Animal входит в пространство имен Anna.FunStuff.
Все библиотеки классов, которые предлагают разработчики Майкрософт, а также других организаций, помещаются в пространства имен. Поэтому, прежде чем использовать код из таких библиотек, необходимо понимать, как работать с пространствами имен.
Строительный блок: Пространство имен Для логического объединения классов одной тематики рекомендуется помещать их в одно пространство имен. Имя пространства должно иметь { содержательный смысл.
Экземпляр или объект приведенного выше класса можно создавать, вызывая конструктор класса.
Если нужно создать много объектов одного пространства имен, то в начале программы в предложении «using»
можно указать пространство имен.
Тогда компьютер сам будет находить классы в этом пространстве.
Наследование Так как эта книга адресована тем, кто только начинает знакомиться с искусством программирования, мы не станем рассматривать слишком сложные вещи, поэтому расскажем о наследовании немного.
Иногда вам будет встречаться объявление классов следующего вида:
class MyFancyClass : Form...
Сравните его с обычным объявлением класса:
class MyFancyClass...
Поясним, что же происходит, когда после имени класса через двоеточие указывается имя другого класса и объявлению придается совсем другой смысл.
Наследование среди людей Человек, как правило, наследует определенные качества от своих родителей. У вас может быть цвет волос как у мамы, а нос — папин.
Это не означает, что вы полностью похожи на своих родителей. Несомненно, вы обладаете различными уникальными качествами и способностями, но определенные свойства характера и физические особенности «заложены» в вас при рождении.
Наследование кода При написании программного кода было бы полезно иметь возможность наследования всего набора способностей существующего класса, будь то собственный класс или чей-то еще.
Приведем пример. Определим два класса — Animal и Bird. Класс Bird объявим наследником класса Animal.
class Animal //Поля класса public string kindOfAnimal;
public string name;
public int numberOfLegs;
public int height;
public int length;
public string color;
bool hasTail;
protected bool isMammal;
private bool spellingCorrect;
// Класс “Bird” — наследник класса “Animal” class Bird : Animal public string featherColor;
В реальном мире птица — это вид животного, но у птиц есть свои отличительные признаки, характерные только для них. Тогда имеет смысл классу Bird наследовать все признаки класса Animal и стать обладателем ряда дополнительных признаков. В данном случае мы определим одно специальное поле, характерное для птиц, — featherColor — цвет перьев.
Итак, пишем:
class Bird : Animal...
Таким образом мы сообщаем следующее: «Я определяю новый класс Bird, но он должен автоматически наследовать все свойства класса Animal». Иными словами, класс Bird является производным от класса Animal.
При создании экземпляра Bird мы можем обращаться как к полям, определенным в классе Bird, так и к наследуемым полям класса Animal, конечно, если эти поля не являются закрытыми:
Bird b = new Bird();
b.kindOfAnimal = “Орел”;
b.isMammal = false;
b.featherColor = “темно-желтый”;
//Примечание редактора. Это фрагмент кода, о корректности которого нельзя судить без знания контекста. Доступ к свойствам зависит от того, где появляется приведенный выше текст: если из метода класса Bird, то доступ к защищенному (protected) свойству isMammal разрешен, поскольку класс Bird — потомок класса Animal; если же из метода класса клиента, то это свойство будет недоступно.
Более важное замечание: о наследовании можно говорить, только когда объекты двух классов связаны отношением «является». Каждая птица (объект класса Bird) является животным (объектом класса Animal). Поэтому класс Bird может быть объявлен наследником класса Animal, но класс Car, автомобили, нельзя объявлять наследником класса Animal, поскольку автомобили не являются животными.
Для простоты мы не включили в программу объявление методов в классах Animal и Bird, но для них действуют те же правила доступа, что и для полей. Производный класс может вызывать любые методы в родительском классе, если они не объявлены закрытыми.
Наследование возможностей работы с окнами Предположим, вам нужно написать программу, выполняемую в обычном окне, и понадобятся возможности изменения размера окна, его разворачивания, сворачивания, перетаскивания и некоторые другие. Имеет смысл, чтобы ваш класс «наследовал» возможности класса, который уже работает с подобным типом интерфейса. Обычным выбором родительского класса становится класс System.Windows.Forms.Form.
В таком случае пишем:
class MyFancyClass : Form...
Фактически мы говорим: «Я создаю собственный класс, но он должен автоматически наследовать все возможности класса Form».
Когда следует использовать наследование Для использования класса совсем не обязательно наследовать от него поля! Наследование лучше всего подходит для тех случаев, когда то, чего вы пытаетесь добиться, можно получить от существующего класса, дополнительно расширив его или настроив.
Строительный блок: Наследование Класс может наследовать свойства и действия другого класса.
Класс «Guitarist» наследует все поля из класса «», а кроме того, имеет два собственных поля.
Имя класса Musician, написанное после двоеточия, сообщает компьютеру, что новый класс «Guitarist»
наследует поля и методы родительского класса «Musician».
Создав объект класса Guitarist, можно установить его свойства, если они являются открытыми для доступа.
Часть 3. Программирование в.NET Framework Что такое.NET Framework?
Программировать на языке C# без.NET Framework — это все равно что писать ручкой без чернил. Сколько ни води ею по бумаге, написать ничего не удастся.
Так что же такое.NET Framework? Это платформа программирования, разработанная корпорацией Microsoft, и язык C# создавался специально для.нее. Платформа.NET Framework состоит из двух частей.
1. Во-первых, она содержит огромную библиотеку классов, которые можно вызывать из программ, созданных на C#. Такая возможность избавляет от необходимости писать все 2. Во-вторых, в ее состав входит среда выполнения, управляющая запуском и работой готовых программ (это происходит абсолютно незаметно для вас и не вызывает никаких Итак, при написании программы на языке C# (или на любом другом языке.NET) наряду с созданием собственного кода вызываются классы, хранящиеся в библиотеке.
Библиотека.NET framework содержит огромное количество классов, и некоторые из них настолько сложны, что мы даже не будем пытаться рассмотреть все сразу. Расскажем лишь о тех, которые, на наш взгляд, наиболее полезны для начинающих программистов. Со временем вы станете запоминать классы, которыми пользуетесь чаще, чем другими, и постепенно хорошо их освоите. Ведь когда часто берешь в библиотеке любимую книгу, то легко запоминаешь, на какой полке ее искать.
Обращаю ваше внимание: в этой части книги приведено много примеров программ, которые вы должны сначала испытать в работе, а затем попытаться изменить их, чтобы добиться новых результатов. Ранее мы уже рассказывали, как запускать примеры, представленные на сайте http://intuit.ru/software/school/cs2kids/examples.zip.
Как изменять примеры программ и расширять их возможности Я слышу вашевозмущение: «Легко сказать: измени программу! Но откуда мне знать, в каком направлении двигаться? В приведенных примерах используются лишь некоторые методы и классы.NET Framework, но ведь их очень много! Как о них узнать?»
Для этого есть несколько способов:
Просмотреть библиотеку классов.NET Framework SDK (Software Development Kit – набор средств разработки), которая включена в справочную систему Visual C# Express.
Воспользоваться интеллектуальной подсказкой Visual C# Express. Как только вы введете в ее окошко имя пространства имен или класса и поставите точку, автоматически раскроется список всех доступных классов, методов, полей. Достаточно выбрать нужный элемент списка. Например, после ввода «Console.» вы увидите список методов и других элементов класса Console.
Подсказка работает и для методов. Если поставите открывающую скобку после имени метода, то увидите типы параметров, которые он может принимать. Зачастую в C# используются одноименные методы с различными наборами параметров — в таком случае список надо «прокруПрограммирование в.NET Framework чивать» (перемещаться по нему) вверх и вниз при помощи клавиш с изображенными на них стрелками. В следующем примере показано, что произойдет, если набрать Console.WriteLine(.
Visual C# Express подскажет о существовании 19 различных способов вызова метода WriteLine.
Мы прокрутили список вниз до 11-й позиции (см. рисунок ниже).
Консольные приложения Понятие «консоль» пришло к нам из тех времен, когда были популярны большие компьютеры, их называли мейнфреймами. Компания размещала в каком-нибудь помещении один гигантский компьютер, а на рабочих местах служащих устанавливалась только клавиатура и простенький монитор, называвшийся консолью. Клавиатура и монитор подключались к тому самому «монстру», спрятанному от посторонних глаз в отдельной комнате. Такие мониторы не умели отображать графику — только текст. Информация передавалась в мейнфрейм при помощи клавиатуры – основного устройства ввода, а консоль – основное устройство вывода – позволяла компьютеру представлять информацию пользователю.
Сегодня мониторы большинства компьютеров имеют гораздо более совершенные возможности и способны отображать не только текст, но и, например, фотографии.
Однако при выполнении многих задач никаких графических изысков не требуется. Например, программа, получающая какие-либо данные с сервера в Интернете и сохраняющая их в файле на вашем компьютере, должна уметь выводить только два сообщения: «идет получение данных» и «готово». Зачем тратить время на разработку затейливого пользовательского интерфейса, который занимает много памяти? Именно по этой причине в библиотеку.NET включен класс для быстрого написания консольных приложений.
Не стоит относиться снисходительно к консольным приложениям и считать их слишком примитивными. Опытные программисты предпочитают не тратить усилия на интерфейсные ухищрения и работают в основном с консольными приложениями.
Конечно, если вашей программой будет пользоваться кто-то еще, то вы, вероятно, окажете ему большую услугу, сделав интерфейс чуть более дружественным, чем в стандартном консольном приложении.
Некоторые полезные методы:
1. Console.ReadLine — считывает строку символов, введенную с клавиатуры (или иного устройства ввода).
2. Console.WriteLine — выводит текст на экран (или иное устройство вывода) начиная с 3. Console.Write — выводит на экран ряд символов без перехода на новую строку.
Пример программы Следующая программа выводит на экран слово «Ура!» и после этого ожидает нажатия клавиши ВВОД.
Код программы using System;
class PleaseSayUra static void Main() // Выводим слово на экран Console.Write(“Ура!”);
// Ожидаем нажатия клавиши ВВОД Console.ReadLine();
Пример программы Следующая программа:
просит пользователя ввести слово при помощи клавиатуры;
спрашивает, сколько раз это слово должно быть выведено на экран;
выводит слово на экран указанное количество раз, причем в каждом случае с новой Код программы using System;
class WriteAFewLines static void Main() Console.WriteLine(“Введите Ваше любимое слово : “);
// Сохраняем в строковой переменной введенное пользователем слово string favouriteWord = Console.ReadLine();
Console.WriteLine(“Сколько раз его напечатать? “);
// Сохраняем в целочисленной переменной введенное число // (При неправильном вводе числа произойдет ошибка) int numberOfTimes = Convert.ToInt32(Console.ReadLine());
// Выводим на экран слово указанное количество раз for (int i = 0; i < numberOfTimes; i++) Console.WriteLine(favouriteWord);
// Ожидаем нажатия клавиши ВВОД Console.ReadLine();
Приложения Windows Forms Если вы захотите писать программы, похожие на привычные приложения Windows, то наверняка воспользуетесь классами из пространства имен System.Windows.Forms. Они позволяют задействовать кнопки, списки, текстовые поля, меню, окна сообщений и множество других «элементов управления». Элементы управления — это то, что вы помещаете в форму. Они нужны для вывода информации, например, текстовой (элемент управления Label) или графической (элемент управления PictureBox), либо для выполнения определенных действий, например, выбора значения или перехода к другой форме после нажатия кнопки. Все элементы управления помещаются на форму.
Понятие «форма», принятое в программировании, родственно понятию «форма анкеты»
или «форма документа» из обычной жизни. На форме можно в определенном порядке расположить различные элементы (текст, картинки, поля для заполнения и т. д.). Когда нам дают готоПрограммирование в.NET Framework вую форму документа и просят ее заполнить, мы обычно читаем содержащуюся в ней типовую информацию, а затем вписываем недостающие данные в определенные строки.
В программировании понятие формы во многом похоже: форма позволяет размещать текст, изображения, поля ввода, кнопки и т. п., добиваясь их точного расположения на экране. В консольном приложении на экран выводятся только строки текста.
Компания Майкрософт предоставила в составе библиотеки классов.NET Framework огромное количество «элементов управления», которые можно помещать на формы. Освоив этот инструмент, вы сможете быстро создавать эффектные приложения.
Некоторые полезные классы из пространства имен System.Windows.Forms Вот некоторые элементы управления, которые можно размещать на формах:
ListBox (Список).
CheckBox (Флажок).
RadioButton (Переключатель).
MessageBox (Окно сообщений).
TabControl (Управление вкладками).
Toolbar (Панель инструментов).
TreeView (Дерево).
DataGrid (Сетка данных).
PictureBox (Изображение).
RichTextBox (Текстовое поле с поддержкой формата RTF).
Работа с примерами программ Windows Forms в Visual C# Express Возможно, вы предпочтете не использовать уже заготовленные примеры проектов, а разрабатывать их «с нуля». В таком случае нужно учесть, что для каждого проекта C# Express сразу же создает два файла (с именами Form1.cs и Program.cs) и наполняет их исходным кодом на языке C#, то есть вы изначально получаете простейшую, но полноценную программу. Предлагаемый нами способ работы с уже полученным проектом состоит в выполнении следующих действий:
Удалите файл Form1.cs.
Замените код в файле Program.cs на код примера, с которым вы работаете.
Оба этих действия не понадобятся, если вы открываете программы с помощью команды «Открыть проект» в меню «Файл» и находите нужный проект в той папке, куда его поместили после разархивации.
Пример программы Рассмотрим пример простейшего приложения Windows Forms. Оно всего лишь создает новую форму и выводит определенный текст в заголовок окна формы.
Код программы using System.Windows.Forms;
class SimpleWindowsForm : Form // Метод-конструктор нашего класса public SimpleWindowsForm() // Указываем заголовок окна this.Text = “Это простая форма с заголовком”;
static void Main() // Создаем новый экземпляр класса //и запускаем его на выполнение // В результате на экране дисплея откроется форма Application.Run(new SimpleWindowsForm());
Пример программы Следующий пример тоже достаточно прост, но мы делаем шаг вперед — размещаем на форме кнопку.
Код программы using System.Windows.Forms;
class SimpleWindowsFormWithButton : Form Button button1;
// Метод-конструктор нашего класса public SimpleWindowsFormWithButton() // Указываем заголовок окна this.Text = “Форма с командной кнопкой”;
// Добавляем кнопку в коллекцию элементов управления формы // Хотя на кнопке написано: “Нажми меня!”, // пока при нажатии ничего не происходит!
button1 = new Button();
button1.Text = “Нажми меня!”;
button1.Top = 100;
button1.Left = 100;
button1.Height = 50;
button1.Width = 70;
this.Controls.Add(button1);
static void Main() // Создаем и запускаем форму Application.Run(new SimpleWindowsFormWithButton());
Пример программы Кнопку на форму мы поместили, но при нажатии на нее ничего не происходит. Это скучно.
Нам нужно описать метод, который будет выполнять какое-либо действие при нажатии на кнопку. Пусть при этом текст в заголовке окна будет меняться. Поскольку такой метод отслеживает наступление некоторого события (в нашем случае – нажатие на кнопку) и затем каким-то образом обрабатывает его, он, напомним, называется «обработчик события». Кроме того, надо привязать обработчик события к соответствующему событию, то есть к нажатию на кнопку.
Код программы using System;
using System.Windows.Forms;
using System.Drawing;
class FormWithWorkingButton : Form Button mrButton;
// Метод-конструктор нашего класса public FormWithWorkingButton() // Указываем заголовок окна this.Text = “Форма с работающей кнопкой!”;
// Добавляем кнопку и привязываем ее к обработчику события mrButton = new Button();
mrButton.Text = “Нажми меня”;
mrButton.Height = 50;