Тверской государственный университет
Опубликован: 02.12.2009 | Доступ: свободный | Студентов: 3450 / 677 | Оценка: 4.41 / 4.23 | Длительность: 09:18:00
ISBN: 978-5-9963-0259-8
Лекция 2:

Типы и классы. Переменные и объекты

Константы

Константы C# могут появляться, как обычно, в виде литералов и именованных констант. Вот пример константы, заданной литералом и стоящей в правой части оператора присваивания

y = 7.7f;

Значение константы "7.7f" является одновременно ее именем, оно же позволяет однозначно определить тип константы. Заметьте, иногда, как в данном случае, приходится добавлять к значению специальные символы для точного указания типа. Я не буду останавливаться на этих подробностях. Если возникает необходимость уточнить, как записываются литералы, достаточно получить справку по этой теме.

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

/// <summary>
    /// Константы
    /// </summary>
    public void Constants()
    {
      const int SMALL_SIZE = 38, LARGE_SIZE =58;
      const int MIDDLE_SIZE = (SMALL_SIZE + LARGE_SIZE)/2;
      const double PI = 3.141593;
      // LARGE_SIZE = 60; //Значение константы нельзя изменить.    
    }//Constants

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

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

Типы и классы

Язык C# является языком объектного программирования. Все типы - встроенные и пользовательские - определены как классы, связанные отношением наследования. Родительским, базовым классом является класс object. Все остальные типы или, точнее, классы являются его потомками, наследуя методы этого класса. У класса object есть четыре наследуемых метода:

  • 1. bool Equals(object obj) - проверяет эквивалентность текущего объекта и объекта, переданного в качестве аргумента;
  • 2. System.Type GetType() - возвращает системный тип текущего объекта;
  • 3. string ToString() - возвращает строку, связанную с объектом. Для арифметических типов возвращается значение, преобразованное в строку;
  • 4. int GetHashCode() - служит как хэш-функция в соответствующих алгоритмах поиска по ключу при хранении данных в хэш-таблицах.

Естественно, что все встроенные типы нужным образом переопределяют методы родителя и добавляют собственные методы и свойства. Учитывая, что и классы, создаваемые пользователем, также являются потомками класса object, в них, как правило, необходимо переопределить методы родителя, поскольку реализация родителя, предоставляемая по умолчанию, не будет обеспечивать нужный эффект.

Рассмотрим вполне корректный в языке C# пример объявления переменных и присваивания им значений:

int x = 1;
int v = new Int32();
v = 007;
string s1 = "Agent";
s1 = s1 + v.ToString() +x.ToString();

В этом примере переменная x объявляется как обычная переменная типа int. В то же время для объявления переменной v того же типа int используется стиль, принятый для объектов. В объявлении применяется конструкция new и вызов конструктора класса. В операторе присваивания, записанном в последней строке фрагмента, для обеих переменных вызывается метод ToString, как это делается при работе с объектами. Этот метод, наследуемый от родительского класса object, переопределенный в классе int, возвращает строку с записью целого. Сообщу еще, что класс int не только наследует методы родителя - класса object, но и дополнительно определяет метод CompareTo, выполняющий сравнение целых, и метод GetTypeCode, возвращающий системный код типа. Для класса int определены также статические методы и поля, о которых расскажу чуть позже.

Так что же такое поле этого int, спросите Вы? Ведь ранее говорилось, что int относится к значимым - value -типам, следовательно, он хранит в стеке значения своих переменных, в то время как объекты должны задаваться ссылками. С другой стороны, создание экземпляра с помощью конструктора, вызов методов, наконец, существование родительского класса object - все это указывает на то, что int - это настоящий класс. В зависимости от контекста x может восприниматься как переменная типа int или как объект класса int. Это же верно и для всех остальных value -типов. Замечу еще, что все значимые типы фактически реализованы как структуры, представляющие частный случай класса.

Остается понять, для чего в языке C# введена такая двойственность. Для int и других значимых типов сохранена концепция типа не только из-за ностальгических воспоминаний о типах. Дело в том, что значимые типы эффективнее в реализации, им проще отводить память, так что именно соображения эффективности реализации заставили авторов языка сохранить значимые типы. Более важно, что зачастую необходимо оперировать значениями, а не ссылками на них, хотя бы из-за различий в семантике присваивания для переменных ссылочных и значимых типов.

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

Проекты, содержащие несколько форм

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

Архитектура проекта является примером типовой архитектуры проекта с главной кнопочной формой. Главная форма, задающая точку входа в проект, представляет форму с множеством командных кнопок. Всякий раз, когда в проект добавляется новый интерфейсный класс и соответствующая ему форма, в класс главной формы добавляется объект нового класса, а на главную форму добавляется новая командная кнопка, обработчик события Click которой будет создавать объект этого класса и вызывать метод Show для показа формы соответствующего интерфейсного класса.

Обработчик события Click, создающий объект интерфейсного класса FormLocals и вызывающий связанную с ним форму, имеет вид:

private void button1_Click(object sender, EventArgs e)
  {
     FormLocals testLocalsForm = new FormLocals();
     testLocalsForm.Show();
  }

Модальные и немодальные формы. Методы Show, ShowDialog, Hide,Close

В проекте с множеством форм одновременно на экране может быть открыто несколько форм. Может ли пользователь переключаться на работу с той или иной формой? Все зависит от того, как открыта форма. Каждую форму можно открыть как модальную или как немодальную. Хотя термин "модальная форма" широко используется, удобнее говорить, что форма может быть открыта как "диалоговое окно" (модальная форма) или как обычное окно (немодальная форма). Если форма, как в наших примерах, открывается методом Show, то она задает обычное окно; если форму открывать методом ShowDialog, то она открывается как диалоговое окно. В чем разница? Из диалогового окна нельзя выйти, не закончив диалог и не закрыв форму. Открыв диалоговое окно, нельзя переключиться на работу с другой формой, не закончив диалог. Закрыть диалоговое окно можно разными способами. Можно щелкнуть по крестику, расположенному в правом верхнем углу формы, закрывая ее "грубым" способом. В диалоговом окне часто размещают командные кнопки с предопределенной семантикой - "OK", "Cancel" и другие. Щелчки по этим кнопкам также приводят к закрытию диалогового окна. У метода ShowDialog есть еще одна особенность: в отличие от метода Show он реализован как функция, возвращающая значение типа System.DialogResult. Благодаря этому можно узнать, какая кнопка была нажата при завершении диалога (например, OK или Cancel).

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

Для показа формы можно применять два метода - Show и ShowDialog, для скрытия формы можно также применять два метода - Hide и Close. Первый из этих методов скрывает форму, второй - закрывает. Для диалоговых окон можно применять как метод Hide, так и метод Close: эффект будет одинаков - диалоговое окно будет закрыто. Затем его можно открыть и показать методом Show. Метод Hide можно применять и для немодальных форм, открытых методом Show. Окно, открытое не для диалога, можно временно скрыть, вызвав метод Hide, а затем показать, вызвав метод Show. Но вот на что следует обратить особое внимание. После закрытия недиалогового окна - либо при вызове метода Close, либо "грубым" способом нажатия на крестик в окне формы - показать затем форму, вызвав метод Show, уже не удастся. Причина в том, что при закрытии формы сам объект, задающий форму, продолжает существовать, но ресурсы освобождаются и графическое окно уже не связано с программным объектом. Поскольку конечный пользователь всегда может применить грубую силу для закрытия формы, обратите внимание, что в соответствующих обработчиках события создание объекта, задающего форму, предшествует вызову метода Show. Для диалоговых окон объект можно было бы создать только один раз, например, в конструкторе главной кнопочной формы.

Я добавил в проект диалоговую форму, в которой разместил командные кнопки OK и Cancel с предустановленной семантикой, ввел еще некоторые изменения, чтобы проиграть все возможные варианты показа, скрытия и закрытия форм, открываемых как модальные (диалоговые окна), так и немодальные. Не буду приводить подробного описания этих экспериментов, но надеюсь, что при желании читатели их смогут провести самостоятельно.

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

Задачи

  • 1. Построить консольное приложение. Дать ему имя, разместить в выбранной директории. Проанализировать созданный программный текст. Познакомиться со средой разработки Visual Studio .Net. Выполнить приложение в пошаговом отладочном режиме.
  • 2. Построить Windows-приложение. Дать ему имя, разместить в выбранной директории. Проанализировать созданный программный текст. Познакомиться со средой разработки Visual Studio .Net. Выполнить приложение в пошаговом отладочном режиме.
  • 3. Построить консольное приложение "Здравствуй, Мир!", выводящее на консоль строку приветствия.
  • 4. Построить Windows-приложение "Здравствуй, Мир!" с командной кнопкой и текстовым окном. Приложение выводит в текстовое окно строку приветствия при нажатии командной кнопки.
  • 5. Построить консольное приложение "Здравствуй, человек!". Приложение вводит с консоли имя и выводит на консоль строку приветствия, используя введенное имя. Если вводится пустая строка, то выводится текст "Здравствуй, человек!".
  • 6. Построить Windows-приложение "Здравствуй, человек!" с командной кнопкой и двумя текстовыми окнами. Пользователь вводит имя в первое текстовое окно и при нажатии командной кнопки получает во втором текстовом окне строку приветствия, использующую введенное имя. Если вводится пустая строка, то выводится текст "Здравствуй, человек!".
  • 7. Построить консольное приложение "Здравствуйте, люди!". Приложение вводит с консоли имя и выводит на консоль строку приветствия, используя введенное имя. Вводу имени предшествует приглашение к вводу "Введите имя".
  • 8. Построить Windows-приложение "Здравствуйте, люди!" с командной кнопкой и двумя текстовыми окнами. Пользователь вводит имя в первое текстовое окно и при нажатии командной кнопки получает во втором текстовом окне строку приветствия, использующую введенное имя. С каждым текстовым окном связывается окно метки, в котором дается описание назначения текстового окна.
  • 9. Построить циклическое консольное приложение "Здравствуй, человек!". Приложение вводит с консоли имя и выводит на консоль строку приветствия, используя введенное имя. Вводу имени предшествует приглашение к вводу "Введите имя". После приветствия на консоль выводится запрос на продолжение работы "Продолжить работу? (да, нет)". В зависимости от введенного ответа повторяется приветствие или приложение заканчивает работу.

    Указание к задаче. Представьте выполняемый блок оператором цикла следующего вида:

    do
    {
      …
    }while((answer=="Да") || (answer=="да" ));
    Здесь answer - переменная, содержащая ответ пользователя на предложение продолжения работы.

Встроенные типы данных. Ввод-вывод данных

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

  • 10. Построить циклическое консольное приложение "Целочисленные типы". Приложение поочередно вводит с консоли значения целочисленных типов: sbyte, byte, short, ushort, int, uint, long, ulong. Вводу значения предшествует приглашение к вводу. После завершения ввода приложения выводит все введенные значения с указанием их типа. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу или выходящих за пределы интервала возможных значений типа.
  • 11. Построить Windows-приложение "Целочисленные типы" с 16-ю помеченными текстовыми окнами и двумя командными кнопками Пользователь вводит значения целочисленных типов: sbyte, byte, short, ushort, int, uint, long, ulong в первые 8 окон. По нажатию командной кнопки "Ввод значений" данные из текстовых окно становятся значениями переменных соответствующих типов. По нажатию командной кнопки "Вывод значений" значения переменных соответствующих типов передаются в текстовые окна, предназначенные для вывода значений. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу или выходящих за пределы интервала возможных значений типа.
  • 12. Построить циклическое консольное приложение "Вещественные типы". Приложение поочередно вводит с консоли значения вещественных типов: float, double. Вводу значения предшествует приглашение к вводу. После завершения ввода приложения выводит все введенные значения с указанием их типа. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу или выходящих за пределы интервала возможных значений типа.
  • 13. Построить Windows-приложение "Вещественные типы" с 4-мя помеченными текстовыми окнами и двумя командными кнопками Пользователь вводит значения вещественных типов: float, double в первые 2 окна. По нажатию командной кнопки "Ввод значений" данные из текстовых окно становятся значениями переменных соответствующих типов. По нажатию командной кнопки "Вывод значений" значения переменных соответствующих типов передаются в текстовые окна, предназначенные для вывода значений. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу или выходящих за пределы интервала возможных значений типа.
  • 14. Построить циклическое консольное приложение "Decimal тип". Приложение поочередно вводит с консоли значения типа Decimal c целой и дробной частью. Вводу значения предшествует приглашение к вводу. После завершения ввода приложение выводит введенное значение с указанием типа. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу или выходящих за пределы интервала возможных значений типа.
  • 15. Построить Windows-приложение "Decimal тип" с 2-мя помеченными текстовыми окнами и двумя командными кнопками Пользователь вводит значения типа Decimal c целой и дробной частью в текстовое окно. По нажатию командной кнопки "Ввод значений" данные из текстового окна становятся значением переменной соответствующего типа. По нажатию командной кнопки "Вывод значений" значение переменной передается в текстовое окно, предназначенное для вывода значений. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу или выходящих за пределы интервала возможных значений типа.
  • 16. Построить циклическое консольное приложение "Строковый тип". Приложение поочередно вводит с консоли символы и строки - значения типов char и string. Вводу значения предшествует приглашение к вводу. После завершения ввода приложение выводит введенное значение с указанием типа. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу.
  • 17. Построить Windows-приложение "Строковый тип". Пользователь вводит значения в текстовое окно. По нажатию командной кнопки "Ввод значений" данные из текстового окна становятся значением переменной соответствующего типа. По нажатию командной кнопки "Вывод значений" значение переменной передается в текстовое окно, предназначенное для вывода значений. Проанализировать, что происходит при вводе значений, не соответствующих требуемому типу.
  • 18. Построить циклическое консольное меню-приложение "Выбор". Приложение выводит на консоль нумерованные пункты меню, предлагая затем пользователю задать номер выбранного им пункта меню. При вводе пользователем соответствующего номера начинает выполняться выбранный пункт меню. В данной задаче команды меню определяют тип значений, вводимых и выводимых на консоль.
  • 19. Построить Windows-приложение "Выбор". В одно из текстовых окон пользователь вводит тип переменной, в другое - значение. По нажатию командной кнопки "Ввод значений" данные из текстового окна становятся значением переменной, тип которой задан в первом текстовом окне. По нажатию командной кнопки "Вывод значений" значение переменной передается в текстовое окно, предназначенное для вывода значений.

Контролируемый ввод данных

В эадачах этого раздела необходимо организовать контроль данных, вводимых пользователем.

  • 20. Постройте консольное приложение, в котором вводится имя пользователя. Имя должно отвечать правилам, принятым в русском языке: составлено из букв кириллицы. Первый символ должен быть заглавной буквой, остальные - строчными буквами.
  • 21. Постройте Windows-приложение, в котором вводится имя пользователя. Имя должно отвечать правилам, принятым в русском языке: составлено из букв кириллицы. Первый символ должен быть заглавной буквой, остальные - строчными буквами.
  • 22. Постройте консольное приложение, в котором вводится возраст пользователя. Возраст должен отвечать заданным правилам: быть целым числом из фиксированного диапазона.
  • 23. Постройте Windows-приложение, в котором вводится возраст пользователя. Возраст должен отвечать заданным правилам: быть целым числом из фиксированного диапазона.
  • 24. Постройте консольное приложение, в котором вводится выбранная пользователем специальность, принадлежащая фиксированному списку специальностей.
  • 25. Постройте Windows-приложение, в котором вводится выбранная пользователем специальность, принадлежащая фиксированному списку специальностей.
  • 26. Постройте консольное приложение, в котором вводятся номера телефонов пользователя (домашний, мобильный). Номера должны быть заданы в соответствии с фиксированным шаблоном. Один или оба номера могут отсутствовать.
  • 27. Постройте Windows-приложение, в котором вводятся номера телефонов пользователя (домашний, мобильный). Номера должны быть заданы в соответствии с фиксированным шаблоном. Один или оба номера могут отсутствовать.
  • 28. Постройте консольное приложение, в котором вводятся анкетные данные пользователя, являющегося студентом (ФИО, возраст, телефон, факультет, номер группы). Значения каждого поля должны отвечать заданным правилам (смотри предыдущие задачи этого раздела).
  • 29. Постройте Windows-приложение, в котором вводятся анкетные данные пользователя, являющегося студентом (ФИО, возраст, телефон, факультет, номер группы). Значения каждого поля должны отвечать заданным правилам (смотри предыдущие задачи этого раздела).
  • 30. Постройте Windows-приложение, в котором вводятся данные о владельце машины (ФИО, марка машины, ее номер и цвет). Значения каждого поля должны отвечать заданным правилам.
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Илья Ардов
Илья Ардов

Добрый день!

Я записан на программу. Куда высылать договор и диплом?