Полное руководство. С# 4.0
Шрифт:
Вот к какому результату приводит выполнение этой программы. В ветви case 1 В ветви case 3 В ветви default В ветви case 2 В ветви case 1 В ветви case 3 В ветви default В ветви case 3 В ветви default В ветви default
Обратите внимание на то, как оператор goto используется в операторе switch для перехода к другим его ветвям case иди к ветви default. Обратите также внимание на то, что ветви case не оканчиваются оператором break. Благодаря тому что опе ратор goto препятствует последовательному переходу от одной ветви case к другой, упоминавшееся ранее правило недопущения "провалов" не нарушается, а следова тельно, необходимость в применении оператора break в данном случае отпадает. Но как пояснялось выше, оператор goto нельзя использовать как внешнее средство для безусловного перехода к оператору switch. Так, если удалить символы комментария
приведенная выше программа не будет скомпилирована. Откровенно говоря, при менение оператора goto в операторе switch, в общем, не рекомендуется как стиль программирования, хотя в ряде особых случаев это может принести определенную пользу.
Ниже приведен один из полезных примеров применения оператора goto для выхода из глубоко вложенной части программы. // Продемонстрировать практическое применение оператора goto. using System; class Use_goto { static void Main { int i=0, j=0, k=0; for(i=0; i < 10; i++) { for(j=0; j < 10; j++ ) { for(k=0; k < 10; k++) { Console.WriteLine("i, j, k: " + i + " " + j + " " + k); if(k == 3) goto stop; } } } stop: Console.WriteLine("Остановлено! i, j, k: " + i + ", " + j + " " + k); } }
Выполнение этой программы дает следующий результат. i, j, k: 0 0 0 i, j, k: 0 0 1 i, j, k: 0 0 2 i, j, k: 0 0 3 Остановлено! i, j, k: 0, 0 3
Если бы не оператор goto, то в приведенной выше программе пришлось бы при бегнуть к трем операторам if и break, чтобы выйти из глубоко вложенной части этой программы. В данном случае оператор goto действительно упрощает код. И хотя при веденный выше пример служит лишь для демонстрации применения оператора goto, вполне возможны ситуации, в которых этот оператор может на самом деле оказаться полезным.
И последнее замечание: как следует из приведенного выше примера, из кодового блока можно выйти непосредственно, но войти в него так же непосредственно нельзя.
ГЛАВА 6. Введение в классы, объекты и методы
Эта глава служит введением в классы. Класс составляет основу языка С#, поскольку он определяет характер объекта. Кроме того, класс служит основанием для объектно-ориентированного программирования (ООП). В пределах класса определяются данные и код. А посколь ку классы и объекты относятся к основополагающим эле ментам С#, то для их рассмотрения требуется не одна глава книги. В данной главе рассмотрение классов и объектов на чинается с их главных особенностей. Основные положения о классах
Классы использовались в примерах программ с самого начала этой книги. Разумеется, это были лишь самые про стые классы, что не позволяло выгодно воспользоваться большинством их возможностей. На самом же деле классы намного более эффективны, чем это следует из приведен ных ранее примеров их ограниченного применения.
Начнем рассмотрение классов с основных положений. Класс представляет собой шаблон, по которому определя ется форма объекта. В нем указываются данные и код, кото рый будет оперировать этими данными. В С# используется спецификация класса для построения объектов, которые являются экземплярами класса. Следовательно, класс, по существу, представляет собой ряд схематических описа ний способа построения объекта. При этом очень важно подчеркнуть, что класс является логической абстракцией. Физическое представление класса появится в оперативной памяти лишь после того, как будет создан объект этого класса. Общая форма определения класса
При определении класса объявляются данные, которые он содержит, а также код, оперирующий этими данными. Если самые простые классы могут содержать только код или только данные, то большинство настоящих классов содержит и то и другое.
Вообще говоря, данные содержатся в членах данных, определяемых классом, а код — в функциях-членах. Следует сразу же подчеркнуть, что в C# предусмотрено несколько разновидностей членов данных и функций-членов. Например, к членам данных, назы ваемым также полями, относятся переменные экземпляра и статические переменные, а к функциям-членам — методы, конструкторы, деструкторы, индексаторы, события, операторы и свойства. Ограничимся пока что рассмотрением самых основных компо нентов класса: переменных экземпляра и методов. А далее в этой главе будут представ лены конструкторы и деструкторы. Об остальных разновидностях членов
класса речь пойдет в последующих главах.Класс создается с помощью ключевого слова class. Ниже приведена общая форма определения простого класса, содержащая только переменные экземпляра и методы. class имя_класса { // Объявление переменных экземпляра. доступ тип переменная1; доступ тип переменная2; //... доступ тип переменнаяN; // Объявление методов. доступ возращаемый_тип метод1(параметры) { // тело метода } доступ возращаемый_тип метод2(параметры) { // тело метода } // ... доступ возращаемый_тип методы(параметры) { } }
Обратите внимание на то, что перед каждым объявлением переменной и метода указывается доступ. Это спецификатор доступа, например public, определяющий порядок доступа к данному члену класса. Как упоминалось в главе 2, члены класса мо гут быть как закрытыми (private) в пределах класса, так открытыми (public), т.e. бо лее доступными. Спецификатор доступа определяет тип разрешенного доступа. Ука зывать спецификатор доступа не обязательно, но если он отсутствует, то объявляемый член считается закрытым в пределах класса. Члены с закрытым доступом могут ис пользоваться только другими членами их класса. В примерах программ, приведенных в этой главе, все члены, за исключением метода Main, обозначаются как открытые (public). Это означает, что их можно использовать во всех остальных фрагментах кода — даже в тех, что определены за пределами класса. Мы еще вернемся к обсужде нию спецификаторов доступа в главе 8.
ПРИМЕЧАНИЕ Помимо спецификатора доступа, в объявлении члена класса могут также присутствовать один или несколько модификаторов. О модификаторах речь пойдет далее в этой главе.
Несмотря на отсутствие соответствующего правила в синтаксисе С#, правильно сконструированный класс должен определять одну и только одну логическую сущ ность. Например, класс, в котором хранятся Ф.И.О. и номера телефонов, обычно не со держит сведения о фондовом рынке, среднем уровне осадков, циклах солнечных пятен или другую информацию, не связанную с перечисляемыми фамилиями. Таким об разом, в правильно сконструированном классе должна быть сгруппирована логически связанная информация. Если же в один и тот же класс помещается логически несвя занная информация, то структурированность кода быстро нарушается.
Классы, использовавшиеся в приведенных ранее примерах программ, содержали только один метод: Main. Но в представленной выше общей форме определения класса метод Main не указывается. Этот метод требуется указывать в классе лишь в том случае, если программа начинается с данного класса. Определение класса
Для того чтобы продемонстрировать классы на конкретных примерах, разработаем постепенно класс, инкапсулирующий информацию о зданиях, в том числе о домах, складских помещениях, учреждениях и т.д. В этом классе (назовем его Building) бу дут храниться три элемента информации о зданиях: количество этажей, общая пло щадь и количество жильцов.
Ниже приведен первый вариант класса Building. В нем определены три перемен ные экземпляра: Floors, Area и Occupants. Как видите, в классе Building вообще отсутствуют методы. Это означает, что в настоящий момент этот класс состоит только из данных. (Впоследствии в него будут также введены методы.) class Building { public int Floors; // количество этажей public int Area; // общая площадь здания public int Occupants; // количество жильцов }
Переменные экземпляра, определенные в классе Building, демонстрируют общий порядок объявления переменных экземпляра. Ниже приведена общая форма для объ явления переменных экземпляра: доступ тип имя_переменной;
где доступ обозначает вид доступа; тип — конкретный тип переменной, а имя_пере- менной — имя, присваиваемое переменной. Следовательно, за исключением специфи катора доступа, переменная экземпляра объявляется таким же образом, как и локаль ная переменная. Все переменные объявлены в классе Building с предваряющим их модификатором доступа public. Как пояснялось выше, благодаря этому они стано вятся доступными за пределами класса Building.
Определение class обозначает создание нового типа данных. В данном случае но вый тип данных называется Building. С помощью этого имени могут быть объявлены объекты типа Building. Не следует, однако, забывать, что объявление class лишь описывает тип, но не создает конкретный объект. Следовательно, в приведенном выше фрагменте кода объекты типа Building не создаются.