Приветствую Вас ГостьСуббота, 18.05.2024, 20:29

Light Midnight Inc.


Каталог статей

Главная » Статьи » Программирование » C#

C# для вундеркиндов. Часть 2.5. Учимся общаться с компьютером

Конструкторы с параметрами

В метод-конструктор можно включить параметры. Приведем пример класса с двумя различными методами-конструкторами:

 class Person
 {
 // Поля

 string firstName;
 string lastName;

 // Первый метод-конструктор

 public Person()
 {
 firstName = "Johnny";
 lastName = "Rocket";
 }

 // Второй метод-конструктор

 public Person( string f, string l )
 {
 this.firstName = f;
 this.lastName = l;
 }
 }
 

И теперь у нас есть два разных способа конструирования объекта:

Например, этот:

Person p = new Person();

И в поле p.lastName будет автоматически подставлено значение «Rocket».

Или же этот:

Person p = new Person( "Jiminy", "Cricket" );

И в поле p.lastName будет подставлено значение «Cricket».

Помните, что слово «this» относится к «тому объекту, который мы создаем". То есть, фактически говорится «подставлять в поля имени и фамилии этого нового объекта любые значения, передаваемые методу-конструктору».

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

В компьютерном мире в основном встречаются следующие события:

  • Нажатие кнопки на экране монитора

  • Истечение времени таймера

  • Перемещение мыши

  • Нажатие клавиши на клавиатуре

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

Давайте рассмотрим пример с нажатием кнопки, поскольку это, возможно, наиболее распространенное событие, и детально разберем порядок работы. Допустим, в вашей программе есть объект кнопки с именем mrButton и словами «Click me» на ней.

Даже знаете что, попробуйте делать все сами по ходу обсуждения. Для начала:

  • Чтобы запустить Visual C# Express в меню «Пуск» укажите «Все программы» и затем «Microsoft Visual C# 2005 Express Edition».

  • Создайте новый проект приложения Windows: В меню File(«Файл») выберите Create project(«Создать проект») и затем выберите тип проекта Windows Application («Приложение Windows»).

  • В Visual C# Express откроется несколько файлов с «кодом-скелетом» программы.

  • В окне обозревателя решений справа (где перечислены все файлы) удалите файл с именем Form1.cs.

  • Дважды щелкните имя файла Program.cs и удалите весь автоматически вставленный «скелет» кода.

  • Чтобы создать программу с экземпляром кнопки наберите следующий код в окне Program.cs в точности так, как показано ниже (написание слов курсивом или жирным шрифтом можно опустить)

 using System;
 using System.Windows.Forms;

 class MyButtonClass: Form
 {
 private Button mrButton;

 // Метод-конструктор

 public MyButtonClass()
 {
 mrButton = new Button();
 mrButton.Text = "Click me";
 this.Controls.Add(mrButton);
 }

 // Основной метод

 static void Main()
 {
 Application.Run( new MyButtonClass() );
 }
 }
 
  • Выполните программу при помощи клавиши F5 на клавиатуре (или щелкните зеленую кнопку «Выполнить»). Если возникнут сообщения об ошибках, тщательно проверьте код на предмет опечаток. Если программа будет выполнена успешно, то вы должны увидеть форму с кнопкой «Click me». Пока при нажатии на кнопку никаких действий происходить не будет. Совсем не то, что вы ждали, я знаю, но мы придем и к этому.

Событие нажатия кнопки

Указание действия в случае события

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

 using System;
 using System.Windows.Forms;

 class MyButtonClass: Form
 {
 private Button mrButton;

 // Метод-конструктор

 public MyButtonClass()
 {
 mrButton = new Button();
 mrButton.Text = "Click me";
 this.Controls.Add(mrButton);
 }

 // Основной метод

 static void Main()
 {
 Application.Run( new MyButtonClass() );
 }

       // Метод обработчика событий

       void MyButtonClickEventHandler( object sender, EventArgs e )
       {
             mrButton.Text = "You clicked me!";
       }
 }
 

Программа по-прежнему выполняется?

  • Остановите ее (нажмите кнопку X в верхнем правом углу окна, в котором открыта форма)

  • Добавьте выделенный жирным код в вашу программу и нажмите клавишу F5 для выполнения измененной программы.

  • Попробуйте теперь нажать кнопку «Click me» Бррр! И теперь ничего?

Если вы прочитали главу про методы, то узнаете основную структуру приведенного выше метода. Слово «void» означает, что по завершении метода ничего не возвращается. Словом «MyButtonClickEventHandler» мы назвали этот метод.

Тогда все становится немного странным. Возможно вы поймете, что в скобках присутствует два параметра, но они не подходят: ( object sender, EventArgs e ). Мне не хотелось бы сообщать вам такие неприятные новости, но с методами обработчиков событий нельзя использовать собственные типы параметров. При вызове такого метода система сама автоматически подставляет определенные параметры и ничего с этим поделать мы не сможем.

Поэтому придется просто смириться и всегда использовать ожидаемые типы параметров с обработчиком событий. В случае с событием нажатия на кнопку и многими другими, подставляемые параметры имеют тип «object» и «EventArgs». В приведенном выше примере мы выбрали имена параметров «sender» и «e», но мы могли бы выбрать любые имена — для компьютера важны имена типов этих параметров. Например, следующий код будет работать в точности так же, как и код в примере выше. Если хотите, можете сами проверить это, изменив имена параметров в вашей программе на «x» и «y».

 void MyButtonClickEventHandler( object x, EventArgs y )
 {
 mrButton.Text = "You clicked me!";
 }
 

В первом параметре обычно содержится некоторая информация об объекте, инициировавшем событие. Второй параметр относится к данным о самом событии.

Также следует знать следующее — несмотря на то, что системой всегда подставляются некоторые значения в эти два параметра, часто не будет необходимости в их использовании — они отправляются в метод обработчика событий «на всякий случай».

Подключение метода обработчика событий к событию

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

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

Код для связывания события объекта с методом обработчика события выглядит тоже несколько странно. И мы опять выделим его жирным.

 using System;
 using System.Windows.Forms;

 class MyButtonClass : Form
 {
 private Button mrButton;

 // Метод-конструктор

 public MyButtonClass()
 {
 mrButton = new Button();
 mrButton.Text = "Click me";
 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 = "You clicked me!";
 }
 }
 

С компьютерного на наш язык это можно перевести следующим образом:

К событию нажатия на кнопку добавить новый метод обработчика событий, который называется MyButtonClickEventHandler.

Итак, при нажатии на кнопку, приведенная выше строка кода направляет программу к методу обработчика событий. При его выполнении надпись на кнопке меняется на «You clicked me!»

Чтобы попробовать этот код, остановите свою программу, добавьте в нее выделенный жирным код (в соответствующее место) и нажмите клавишу F5 для выполнения программы. Нажмите на кнопку и ее надпись изменится. Рабочую программу — пример события нажатия на кнопку можно найти в папке примеров к этой книге (Программа 5).

В этом разделе мы опишем основную структуру метода обработчика событий мыши. Вероятно, в этом случае вы захотите использовать информацию, подставляемую в параметр 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. г. Алматы. Республика Казахстан.

Адрес с таким же успехом можно написать и наоборот:

  • Российская Федерация. г. Москва. Улица им. Ленина, 17.

  • Республика Казахстан. г. Алматы. Улица им. Ленина, 82

Теперь письмо должно дойти до адресата без проблем. Например, во втором примере, письмо доставят в Республику Казахстан. Затем из аэропорта его отправят в город Алматы. А потом почтальон пойдет на улицу им. Ленина и найдет дом под номером 82.

Формат [Республика Казахстан.Алматы.ул. им. Ленина] можно считать «пространством имен» для отправки писем.

Пространства имен и программный код

Так какое отношение все это имеет к программированию?

Предположим, что разработчиками корпорации Microsoft написан класс «Point», используемый для рисования фигуры в определенной точке, но вы также создали класс с именем «Point», например для загрузки фотографии человека , указывающего на что-либо.

Очевидно, что эти два класса выполняют абсолютно разные действия, но оба их можно назвать «Point». Откуда программа будет знать с каким классом работать?

Безусловно, имеет смысл как-то использовать разные имена. В среде .NET для этого можно использовать различные пространства имен. Например, так:

  • Microsoft.Drawing.Point

  • Susy.PictureStuff.Point

Имена классов сохранены («Point»), но «пространство имен» перед именем класса позволяет четко видеть, где какой класс. И теперь, если мне нужно использовать класс Point для Susy, я мог бы создать объект Point при помощи следующего метода-конструктора:

 Susy.PictureStuff.Point SusyPoint = new Susy.PictureStuff.Point();
 

А для работы с классом Point от Microsoft я бы использовал следующий код:

 Microsoft.Drawing.Point MicrosoftPoint = new Microsoft.Drawing.Point();
 

Несмотря на то, что оба моих объекта имеют один тип класса «Point», они выполняют разные действия.

Присвоение пространства имен собственному классу

Размещение собственного класса в пространство имен крайне просто. Вместо того, чтобы писать класс следующим образом:

 class Animal
 {
 ...
 }
 

включите его в следующий код:

 namespace Susy
 {
 class Animal
 {
 ...
 }
 }
 

или сделайте так, если хотите:

 namespace Susy.FunStuff
 {
 class Animal
 {
 ...
 }
 }
 

Можно создать любое пространство имен, которое, как вам кажется, имеет смысл. Просто разделяйте свои слова точкой (.).

В последнем приведенном примере, класс Animal теперь входит в пространство имен Susy.FunStuff.

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

Экземпляр или объект приведенного выше класса можно рассматривать при помощи метода-конструктора класса следующим образом:

Или, если бы нам нужно было использовать много объектов из одного пространства имен, и при этом не хотелось бы каждый раз писать «Charles.SchoolUtilities», то мы могли бы употребить ключевое слово «using» в начале программы, чтобы сообщить компьютеру, что в дальнейшем будем применять это пространство имен. Например:

// говорим компьютеру, что будем использовать классы из этого пространства имен

using Charles.SchoolUtilities;

// создание объекта Animal из пространства имен Charles.SchoolUtilities

Animal cat = new Animal();

Строительный блок: Пространства имен

Для логического объединения сходных классов и их различения рекомендуется всегда помещать класс в значимоепространство имен.

 

 namespace Charles.SchoolUtilities
 {
 class Animal
 {

 }
 }
 
 Charles.SchoolUtilities.Animal
 cat = new Charles.SchoolUtilities.Animal();
 

Так как целью книги является только знакомство с программированием, мы не станем рассматривать слишком сложные вещи, поэтому не расскажем многого о наследовании.

Однако, поскольку иногда вам будет встречаться объявление классов следующего вида

 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;
 …
 }

 class Bird : Animal // Класс «Bird» наследует от класса «Animal»
 {
 public string featherColor;
 …
 }
 

В реальном мире птица — это вид животного, но некоторые признаки птиц не соответствуют признакам всех животных. Тогда имеет смысл классу Bird перенимать все признаки класса Animal и иметь ряд дополнительных признаков. В этом случае мы определили одно специальное поле только для птиц — featherColor.

Итак, когда мы пишем

 class Bird : Animal
 {
 ...
 }
 

мы фактически говорим: «Я определяю новый класс "Bird”, но он должен автоматически наследовать все свойства класса «Animal». Часто говорят, что класс «Bird»является производным от класса «Animal».

При создании экземпляра «Bird» мы можем тут же обращаться к полям как класса «Animal», так и «Bird» (если они не являются закрытыми):

 Bird b = new Bird();
 b.kindOfAnimal = "Tawny Eagle”;
 b.isMammal = false;
 b.featherColor = "Tawny”;
 

Чтобы было понятно, мы исключили методы в классах «Animal» и «Bird» в примере выше, но для них действует то же правило. Производный класс может вызывать любые методы в родительском классе, если они не объявлены закрытыми.

Другой пример — Наследование некоторых возможностей работы с окнами в вашей программе.

Предположим, вам нужно написать программу, выполняемую в обычном окне. Вам необходимы возможности изменения размера, разворачивания, сворачивая, перетаскивания окна и некоторые другие. Имеет смысл, чтобы ваш класс «наследовал» возможности класса, который уже работает с подобным типом интерфейса. Обычным выбором становится класс System.Windows.Forms.Form.

Итак, когда мы пишем

 class MyFancyClass : Form
 {
 ...
 }
 

мы фактически говорим: «Я пишу собственный класс, но он должен автоматически наследовать все возможности класса «Form».

Рассматриваемые в этой главе вопросы разбираются на практике в Главе III по System.Windows.Forms.

Когда следует использовать наследование

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

Строительный блок: Наследование

Класс можно заставить наследовать признаки и способности другого класса.

В следующем примере класс «Guitarist» наследует три поля из класса «Musician» и имеет два собственных поля.

Двоеточие (:) говорит компьютеру, что нужно заставить новый класс (Guitarist) наследовать поля класса, написанного справа от двоеточия.

 public class Musician
 {
 public string name;
 public int age;
 public bool canSing;
 }

 public class Guitarist : Musician
 {
 public string guitarType;
 public string guitarBrand;
 }

 Guitarist g = new Guitarist();
 g.name = "Jimbo van Helsdingen";
 g.ageInYears = 28;
 g.canSing = false;
 g.guitarType = ”Acoustic”;
 g.guitarBrand = ”Gibson”;
 


Источник: http://msdn.microsoft.com/ru-ru/library/bb330920(v=vs.80).aspx
Категория: C# | Добавил: Cromartie (25.08.2013)
Просмотров: 885 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Наш опрос
Оцените мой сайт
Всего ответов: 542
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Реклама
Cheсking
Часы
Мини-чат
200
Друзья Сайта
  • Light Midnight - Ваша Еда
  • Light Midnight - Anim as life style
  • Поиск