Методы и конструкторы класса
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Все процедуры и функции, объявленные в классе, являются методами класса. Их описание удовлетворяет обычным правилам синтаксиса. Методы содержат описания операций, доступных над объектами класса, определяя, тем самым, поведение объектов. Все объекты одного класса имеют один и тот же набор методов.

Каждый метод имеет модификатор доступа, принимающий одно из четырех значений: public, private, protected, internal. Модификатором доступа по умолчанию является модификатор private. Независимо от значения модификатора доступа, все методы доступны для вызова при выполнении метода класса. Если методы имеют модификатор доступа private, возможно, опущенный, то тогда они доступны для вызова только внутри методов самого класса. Такие методы считаются закрытыми. Понятно, что класс, у которого все методы закрыты, абсурден, поскольку никто не смог бы вызвать ни один из его методов. Как правило, у класса есть открытые методы, задающие интерфейс класса, и закрытые методы. Интерфейс это лицо класса, именно он определяет, чем класс интересен своим клиентам, что он может делать, какие сервисы предоставляет клиентам. Закрытые методы составляют важную часть класса, позволяя клиентам не вникать во многие детали реализации. Эти методы клиентам класса недоступны, они о них могут ничего не знать, и, самое главное, изменения в закрытых методах никак не отражаются на клиентах класса при условии корректной работы открытых методов.

Если некоторые методы должны быть доступны для методов любого класса B, которому доступен сам класс A, то такие методы снабжаются атрибутом public.

У класса есть методы, решающие специальные задачи, конструкторы, методы-свойства.

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

· имя конструктора фиксировано и совпадает с именем класса,

· для конструктора не задается возвращаемое значение.

 

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

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

Большинство конструкторов класса имеют модификатор доступа public. Помните, что класс создается в интересах своих клиентов. Конструкторы позволяют клиентам класса создавать объекты класса и работать с ними. Конструкторы позволяют не только создать объект класса, но и задать начальные значения полей класса, то есть позволяют создать объект с заданными свойствами. Аргументы конструктора задают значения, позволяющие инициализировать поля класса. Если конструктор по умолчанию, не имеющий аргументов, инициализирует поля класса значениями по умолчанию, то полный конструктор это такой конструктор, который инициализирует поля класса значениями, переданными в аргументах конструктора. Как правило, у полного конструктора число аргументов совпадает с числом полей класса. Каждый аргумент содержит значение соответствующего поля. Поскольку в момент создания объекта не всегда можно задать полный набор его свойств, класс старается обеспечить клиентам широкий набор конструкторов, позволяющих создать и инициализировать объект свойствами, известными клиенту в момент создания того или иного объекта.

Как и когда происходит создание объектов? Чаще всего, при объявлении сущности в момент ее инициализации. РассмотримсозданиетрехобъектовклассаPerson:

Person pers1 = new Person(); pers2 = new Person();

Person pers3= new Person("Петрова");

Сущности pers1, pers2, pers3 класса Person объявляются с инициализацией, задаваемой унарной операцией new, которой в качестве аргумента передается конструктор класса Person. У класса Person несколько конструкторов - это типичная практика, отличающихся сигнатурой. В данном примере в первой строке вызывается конструктор без аргументов, во второй строке для сущности pers3 вызывается конструктор с одним аргументом типа string. Разберем в деталях процесс создания.

Первым делом в стеке для сущностей pers создается ссылка, пока висячая со значением null.

Затем в динамической памяти создается объект структура данных с полями, определяемыми классом Person. Поля объекта инициализируются значениями по умолчанию: ссылочные поля - значением null, арифметические - нулями, строковые - пустой строкой. Эту работу выполняет конструктор по умолчанию, который, можно считать, всегда вызывается в начале процесса создания.

Если поля класса объявлены с инициализацией, то выполняется инициализация полей объекта заданными значениями.

Если вызван конструктор с аргументами, то начинает выполняться тело этого конструктора. Как правило, при этом происходит инициализация тех полей объекта, значения которых переданы конструктору. Так, например, поле fam объекта pers3 получит значение "Петрова".

На заключительном этапе ссылка связывается с созданным объектом.

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

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

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

В языке C# y класса может быть деструктор, но он не занимается удалением объектов и не вызывается нормальным образом в ходе выполнения программы. Деструктор класса, если он есть, вызывается автоматически в процессе сборки мусора. Его роль - в освобождении других ресурсов, например, файлов, открытых объектом. Деструктор C# фактически является финализатором (finalizer), с которым мы еще встретимся при обсуждении исключительных ситуаций. Формальное описание деструктора класса Person:

~Person()

{

//Код деструктора

}

Имя деструктора строится из имени класса с предшествующим ему символом ~ (тильда). Как и у статического конструктора, у деструктора не указывается модификатор доступа.

 

4.3.4. Класс как модульи класс со статическими полями и методами

В языке C# разрешается объявить класс, который не рассматривается как тип данных и у которого сохраняется единственная роль роль модуля. Такой класс объявляется с модификатором static. У такого класса могут быть заданы константы, только статические поля и только статические методы. У него нет конструкторов в обычном смысле этого слова, позволяющих создавать объекты – экземпляры класса. Статический класс не может рассматриваться как тип данных.

Утверждение о том, что для статического класса не создаются объекты, требует уточнения. Один объект создается. Более того, этот статический объект создается всегда, создается автоматически, не требуя выполнения операции new, как это делается для динамически создаваемых объектов. Этот объект получает имя, совпадающее с именем класса. Статический объект, рассматриваемый как модуль класса, создается статическим конструктором, который может быть задан явно, но в случае отсутствия явного задания всегда автоматически добавляется к статическому классу. Конструктор этот вызывается неявно, точный момент его вызова не определен, но гарантируется, что он будет вызван еще до того, как над классом будут выполняться какие-либо операции. Статический конструктор работает точно так же, как и обычный конструктор. Полями создаваемого конструктором объекта будут статические поля и константы класса, которые рассматриваются как статические константы, не требующие задания модификатора static. Информация в полях статического объекта независимо от модификатора доступа открыта для всех статических методов класса, а если эти поля объявлены с модификатором public, то поля доступны и клиентам класса. Так, например, константы PI и E из статического класса Math доступны всем клиентам класса Math.

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

Рассмотрим теперь общую для C# ситуацию, когда класс, представляющий тип данных, объявленный без модификатора static, имеет как обычные, так и статические поля и методы. Такой класс мере играет обе роли типа данных и модуля. Клиент класса, вызвав обычный конструктор,может создать объект класса, содержащий набор обычных полей. Используя этот объект, можно вызвать обычный метод класса, который и будет работать с информацией, хранимой в полях объекта. Но параллельно с этим динамическим процессом создания объектов класса статический конструктор класса, автоматически вызванный, создаст единственный статический объект с именем класса, и этот объект доступен всем клиентам наравне с создаваемыми ими динамическими объектами.

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

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

Напомню, что всякий вызов метода в объектных вычислениях имеет вид x.F(…); где x цель вызова. Обычно целью вызова является динамически созданный объект x, вызывающий обычные методы класса, называемые динамическими или экземплярными методами. В этом случае поля целевого объекта доступны методу и служат глобальным источником информации. Если же необходимо вызвать статический метод (поле), то целью является статический объект, имя которого задается именем класса. Этот объект и его методы доступны и тогда, когда ни один другой динамический объект класса еще не создан.

Ниже еще раз приведем краткое описание всех элементов класса:

· Константы класса хранят неизменяемые значения, связанные с классом.

· Методы реализуют вычисления или другие действия, выполняемые классом или экземпляром.

· Конструкторы реализуют действия по инициализации экземпляров или класса в целом.

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

· Операции задают действия с объектами с помощью знаков операций.

· События определяют уведомления, которые может генерировать класс.

 

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

   [спецификаторы] [const] тип имя [= начальное_значение]

Возможные спецификаторы полей и констант перечислены в таб. 4.3.4-1. Для констант можно использовать только спецификаторы 1–6.

Таблица 4.3.4-1. Спецификаторы полей и констант класса

Спецификатор Описание
1 new Новое описание поля, скрывающее унаследованный элемент класса
2 public Доступ к элементу не ограничен
3 protected Доступ только из данного и производных классов
4 internal Доступ только из данной сборки
5 protected internal Доступ только из данного и производных классов и из данной сборки
6 private Доступ только из данного класса
7 abstract Одно поле для всех экземпляров класса
8 sealed Поле доступно только для чтения
9 static Поле может изменяться другим процессом или системой

По умолчанию элементы класса считаются закрытыми (private). Для полей класса этот вид доступа является предпочтительным. Все методы класса имеют непосредственный доступ к его закрытым полям.

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

Обращение к полю класса выполняется с помощью операции доступа (точка). Справа от точки задается имя поля, слева — имя экземпляра для обычных полей или имя класса для статических. Нарис. 4.3.4-1 приведен пример простого класса Demo и два способа обращения к его полям.

using System; namespace ConsoleApplication1 { class Demo {    public int a = 1;            // поледанных    public const double c = 1.66; // константа public static string s = "Demo"; // статическое поле класса    double y;                    // закрытое поле данных }   class Class1 { static void Main() {      Demo x = new Demo();   //создание экземпляра класса Demo      Console.WriteLine( x.a ); // x.a - обращение к полю класса      Console.WriteLine( Demo.c );// Demo.c - обращение к константе      Console.WriteLine( Demo.s ); // обращение к статическому полю    } } }

Рис.4.3.4-1. Класс Demo, содержащий поля и константу

 

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

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

Синтаксис метода:

 [ спецификаторы ] тип имя_метода ( [ параметры ] )

тело_метода

Первая строка представляет собой заголовок метода. Тело метода, задающее действия, выполняемые методом, чаще всего представляет собой блок.

При описании методов можно использовать спецификаторы 1–7 из таб. 4.3.4-1, имеющие тот же смысл, что и для полей. Чаще всего для методов задается спецификатор доступа public, ведь методы составляют интерфейс класса то, с чем работает пользователь.

Тип определяет, значение какого типа вычисляется с помощью метода. Часто употребляется термин "метод возвращает значение". Если метод не возвращает никакого значения, в его заголовке задается тип void, а оператор return отсутствует.

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

Например, чтобы вычислить значение синуса для вещественной величины x, мы передаем ее в качестве аргумента в метод Sin() класса Math, а чтобы вывести значение этой переменной на экран, мы передаем ее в методWriteLineкласса Console:

double x = 0.1;

double y = Math.Sin(x);

Console.WriteLine(x);

При этом метод Sin()возвращает в точку своего вызова вещественное значение синуса, которое присваивается переменной y, а метод WriteLine ничего не возвращает. Иллюстрация вызова метода приведена на рис. 4.3.4-2.

 

Рис. 4.3.4-2. Вызов метода

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

Параметры, описываемые в заголовке метода, определяют множество значений аргументов, которые можно передавать в метод. Список аргументов при вызове как бы накладывается на список параметров, поэтому они должны попарно соответствовать друг другу. Для каждого параметра должны задаваться его тип и имя. Например, заголовок метода Sin() выглядит следующим образом:

   public static double Sin(double a);

Имя метода вкупе с количеством, типами и спецификаторами его параметров представляет собой сигнатуру метода. В классе не должно быть методов с одинаковыми сигнатурами.

При вызове метода выполняются следующие действия:

1. Вычисляются выражения, стоящие на месте аргументов.

2. Выделяется память под параметры метода в соответствии с их типом.

3. Каждому из параметров сопоставляется соответствующий аргумент (аргументы как бы накладываются на параметры и замещают их).

4. Выполняется тело метода.

5. Если метод возвращает значение, оно передается в точку вызова; если метод имеет тип void, управление передается оператору, следующий после вызова.

 

При этом проверяется соответствие типов аргументов и параметров и при необходимости выполняется их преобразование. При несоответствии типов выдается диагностическое сообщение. Рис. 4.3.4-3 иллюстрирует этот процесс.

using System; namespace ConsoleApplication1 { class Class1 {   static int Max(int a, int b)//метод выбора максимального значения {        if ( a > b ) return a;        else    return b;    }   static void Main()    {        int a = 2, b = 4;        int x = Max( a, b );            // вызовметода Max        Console.WriteLine( x );         // результат: 4          short t1 = 3, t2 = 4;        int y = Max( t1, t2 );          // вызовметода Max        Console.WriteLine( y );             // результат: 4          int z = Max( a + t1, t1 / 2 * b ); // вызовметода Max        Console.WriteLine( z );         // результат: 5    } } }

Рис. 4.3.4-3. Передача параметров методу

Главное требование при передаче параметров состоит в том, что аргументы при вызове метода должны записываться в том же порядке, что и в заголовке метода, и должно существовать неявное преобразование типа каждого аргумента к типу соответствующего параметра. Количество аргументов должно соответствовать количеству параметров. Иллюстрация приведена на рис. 4.3.4-4.

Рис. 4.3.4-4. Соответствие параметров при вызове метода

 

Существуют два способа передачи параметров: по значению и по ссылке.

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

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

В C# для обмена данными между вызывающей и вызываемой функциями предусмотрено четыре типа параметров:

· параметры-значения;

· параметры-ссылки – описываются с помощью ключевого слова ref;

· выходные параметры – описываются с помощью ключевого слова out;

· параметры-массивы – описываются с помощью ключевого слова params.

 

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

   public int Calculate( int a, ref int b, out int c, params int[] d ) …

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

   тип имя

Пример заголовка метода, имеющего один параметр-значение целого типа:

   void P( int x )

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

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

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

Например, пусть в вызывающей функции описаны переменные и им до вызова метода присвоены значения:

int x = 1;

sbyte c = 1;

ushort y = 1;

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

   P( x ); P( c ); P( y ); P( 200 ); P( x / 4 + 1 );

Признаком параметра-ссылки является ключевое слово ref перед описанием параметра:

   ref тип имя

Пример заголовка метода, имеющего один параметр-ссылку целого типа:

   void P( ref int x )

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

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

Проиллюстрируем передачу параметров-значений и параметров-ссылок на примере (рис.4.3.4-4).

using System; namespace ConsoleApplication1 { class Class1 {      static void P( int a, ref int b )    {        a = 44; b = 33;        Console.WriteLine( "внутриметода {0} {1}", a, b );    }    static void Main()    {        int a = 2, b = 4;        Console.WriteLine( "довызова {0} {1}", a, b );        P( a, ref b );        Console.WriteLine( "послевызова {0} {1}", a, b ); } } }

Рис.4.3.4-4. Параметры-значения и параметры-ссылки

 


Результаты работы этой программы:

до вызова 2 4

внутри метода 44 33

после вызова 2 33

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

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

Изменим описание второго параметра в рис.4.3.4-4так, чтобыонсталвыходным
 (рис. 4.3.4-5).

using System; namespace ConsoleApplication1 { class Class1 {      static void P( int a, out int b )    {        a = 44; b = 33;        Console.WriteLine( "внутриметода {0} {1}", a, b );    }    static void Main()    {        int a = 2, b;        P( a, out b );        Console.WriteLine( "послевызова {0} {1}", a, b ); } } }

Рис.4.3.4-5. Выходные параметры

 

При вызове метода перед соответствующим параметром тоже указывается ключевое слово out.

Конструктор предназначен для инициализации объекта. Он вызывается автоматически при создании объекта класса с помощью операции new. Имя конструктора совпадает с именем класса. Ниже перечислены свойства конструкторов:

· Конструктор не возвращает значение, даже типа void.

· Класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации.

· Если программист не указал ни одного конструктора или какие-то поля не были инициализированы, полям значимых типов присваивается нуль, полям ссылочных типов — значение null.

· Конструктор, вызываемый без параметров, называется конструктором по умолчанию.

 

До сих пор мы задавали начальные значения полей класса при описании класса. Это удобно в том случае, когда для всех экземпляров класса начальные значения некоторого поля одинаковы. Если же при создании объектов требуется присваивать полю разные значения, это следует делать в конструкторе. В рис. 4.3.4-6 в класс Demo добавлен конструктор, а поля сделаны закрытыми.

using System; namespace ConsoleApplication1 {     class Demo {    public Demo( int a, double y ) // конструкторспараметрами    {        this.a = a;        this.y = y;    }       public double Gety()     // методполученияполя y    {        return y;    }      int a;      double y; }   class Class1 { static void Main()    {        Demo a = new Demo( 300, 0.002 ); // вызовконструктора        Console.WriteLine( a.Gety() ); // результат: 0,002 Demo b = new Demo( 1, 5.71 ); // вызов конструктора Console.WriteLine( b.Gety() );  // результат: 5,71 } } }

Рис.4.3.4-6. Класс с конструктором

 

Часто бывает удобно задать в классе несколько конструкторов, чтобы обеспечить возможность инициализации объектов разными способами. Все конструкторы должны иметь разные сигнатуры.

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

class Demo {    public Demo( int a )                    //конструктор 1    {        this.a = a;    } public Demo( int a, double y ) : this( a )//вызовконструк. 1 {        this.y = y;    }    ... }

Конструкция, находящаяся после двоеточия, называется инициализатором.

Как вы помните, все классы в C# имеют общего предка – класс object. Конструктор любого класса, если не указан инициализатор, автоматически вызывает конструктор своего предка.

До сих пор речь шла об "обычных" конструкторах, или конструкторах экземпляра. Существует второй тип конструкторов – статические конструкторы, или конструкторы класса. Конструктор экземпляра инициализирует данные экземпляра, конструктор класса – данные класса.

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

Некоторые классы содержат только статические данные и, следовательно, создавать экземпляры таких объектов не имеет смысла. Экземпляры такого класса создавать запрещено. Все элементы такого класса должны явным образом объявляться с модификатором static (константы и вложенные типы классифицируются как статические элементы автоматически). На рис. 4.3.4-3 приведен пример статического класса.

using System; namespace ConsoleApplication1 { static class D {    static int a = 200;    static double b = 0.002;      public static void Print ()    {        Console.WriteLine( "a = " + a );        Console.WriteLine( "b = " + b );    } }   class Class1 { static void Main()    {        D.Print(); } } }

Рис.4.3.4-7. Статический класс

 

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

using System; namespace ConsoleApplication1 { class Monster {       public Monster()    {        this.name = "Noname";        this.health = 100;        this.ammo = 100;    }      public Monster( string name ) : this()    {        this.name = name;    }      public Monster( int health, int ammo, string name )    {        this.name = name;        this.health = health;        this.ammo = ammo;    }      public int GetName()    {        return name;    }    public int GetHealth()    {        return health;    }      public int GetAmmo()    {        return ammo;    }      public void Passport()    {     Console.WriteLine( "Monster {0} \t health = {1} ammo = {2}",                          name, health, ammo );    }      string name;           // закрытыеполя    int health, ammo; }   class Class1 {    static void Main()    {        Monster X = new Monster();        X.Passport();        Monster Vasia = new Monster( "Vasia" );        Vasia.Passport();        Monster Masha = new Monster( 200, 200, "Masha" );        Masha.Passport();    } } }

Рис.4.3.4-8. Класс Monster

 

Результатработыпрограммы:

Monster Noname health = 100 ammo = 100

Monster Vasia health = 100 ammo = 100

Monster Masha health = 200 ammo = 200

 



Дата: 2019-11-01, просмотров: 216.