Шаг 80.
Язык программирования C#. Начала
Знакомство с классами и объектами. Описание класса и создание объекта

    На этом шаге мы рассмотрим порядок выполнения указанных операций.

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

    Описание класса начинается с ключевого слова class. После ключевого слова class указывается название класса. Описание класса разметается в блоке, выделенном фигурными скобками. Ниже приведен шаблон, в соответствии с которым описывается класс:

class имя{
  // Описание класса
}

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

    Методы описываются так:

    Обычный (не статический) метод (а мы рассматриваем именно такие методы) вызывается из объекта. Этот метод имеет доступ к полям объекта. То есть в описании метода можно обращаться к полям объекта, и при этом данные поля как-то дополнительно идентифицировать не нужно (достаточно их описания в теле класса). Метод может возвращать значение (если метод не возвращает значение, то идентификатором типа результата указывается ключевое слово void). В таком случае это значение отождествляется с инструкцией вызова метода. Эту инструкцию можно использовать как операнд в выражениях, подразумевая под ней результат, возвращаемый методом. Также методу могут передаваться аргументы. Это значения, которые метод использует при вызове. Аргументы описываются в круглых скобках после имени метода. Для каждого аргумента указывается тип. При вызове метода фактически передаваемые методу в качестве аргументов значения указываются в круглых скобках после имени метода.

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


Кроме ключевого слова public можно использовать ключевые слова private и protected. С ключевым словом private описывают закрытые члены класса. Другими словами, если нужно сделать поле или метод закрытыми, то это поле или метод описываются с ключевым словом private или вообще без ключевого слова, определяющего уровень доступа. Ключевое слово protected используют при описании защищенных членов класса. Защищенные члены класса обсуждаются в рамках шагов, связанных с наследованием.

    Например, ниже приведено описание класса с одним целочисленным полем.

class MyClass {
  // Целочисленное поле:
  public int number;
}

    Класс называется MyClass, и содержит он всего одно поле, которое называется number, является целочисленным (тип int - то есть значением поля может быть целое число) и открытым (описано с ключевым словом public).

    А вот еще один пример описания класса:

class MyClass {
  // Целочисленное поле: 
  public int number;
  // Символьное поле: 
  public char symbol;
  // Метод:
  public void show() {
    // Отображение значений полей:
    Console.WriteLine("Целое число: " + number);
    Console.WriteLine("Символ: " + symbol);
  }
}

    У этой версии класса MyClass два поля (целочисленное number и символьное symbol). А еще в классе описан метод show(). Метод не возвращает результат (описан с ключевым словом void), и у него нет аргументов. При вызове метода выполняются две команды, которыми в консольное окно выводятся значения полей number и symbol. И вот здесь есть два важных момента. Первый момент связан с тем, что описание метода в классе еще не означает, что код этого метода выполняется. Чтобы код метода выполнялся, метод следует вызвать. А для вызова метода нужен объект, поскольку, если метод не статический, то вызывается он из объекта. Следовательно, необходимо создать объект и вызвать из него метод.


Необходимость вызывать метод из объекта поясним еще на одном отвлеченном примере. Допустим, имеются три кота одной породы: Мурзик, Барсик и Рыжик. Их мы можем отождествлять с объектами. Это объекты некоторого типа или класса, который можно было бы назвать Кот. У каждого из трех котов есть метод, который условно можно назвать "ловить мышей". Если мы хотим поймать реальную мышь, то ловить ее должен совершенно конкретный кот - то есть Мурзик, Барсик или Рыжик. Никакой абстрактный Кот мышей ловить не будет.

    Второй момент связан с тем, что подразумевается под идентификаторами number и symbol в описании метода show() в классе MyClass. Мы уже знаем, что речь идет о полях. Но о полях какого объекта? Ответ, наверное, очевиден: имеются в виду поля объекта, из которого вызывается метод. Другими словами, если из некоторого объекта, созданного на основе класса MyClass, будет вызван метод show(), то этим методом в консольном окне будут отображены значения полей number и symbol объекта, из которого вызван метод.

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

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

  MyClass obj;    . 
Но объявление объектной переменной не приводит к созданию объекта. Объектная переменная может лишь ссылаться на объект. Сам объект нужно создать. Создается объект с помощью оператора new. После оператора new указывается имя класса с пустыми круглыми скобками. Так, для создания объекта класса MyClass используем инструкцию new MyClass() . При выполнении этой инструкции создается объект. Инструкция также возвращает результат - ссылку на созданный объект. Эту ссылку можно присвоить значением объектной переменной (в нашем случае это объектная переменная obj). Поэтому процесс создания объекта класса MyClass может быть описан командами:
  MyClass obj;
  obj = new MyClass();

    Эти две команды можно объединить в одну, которой объявляется объектная переменная и сразу ей значением присваивается ссылка на вновь созданный объект:

  MyClass obj = new MyClass();

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


Рис.1. Реализация объектов в C#


Несложно заметить, что способ реализации объектов напоминает способ реализации массивов: там тоже есть переменная (переменная массива), которая ссылается собственно на массив, а массив создается с помощью оператора new.


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

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


Поля, как и методы, бывают статические и обычные (не статические). Статическое поле существует безотносительно к наличию или отсутствию объектов класса. Оно "не привязано" ни к какому конкретному объекту. Мы же обсуждаем обычные поля. Обычное поле существует только в контексте объекта. Нет объекта - нет поля.

    При обращении к полю объекта используется "точечный синтаксис": указывается имя объекта, точка и после нее - название ноля. Общий формат ссылки выглядит как объект.поле. Например, если в классе MyClass описано поле с названием number и на основании этого класса создается объект obj (объектная переменная obj ссылается на созданный объект), то для обращения к полю number объекта obj используем инструкцию obj.number.

    Методы (не статические) вызываются также с использованием "точечного синтаксиса". Для вызова метода из объекта необходимо указать имя объекта и через точку название метода (с аргументами, передаваемыми методу - если они нужны). Выглядит это как объект.метод (аргументы). Например, если мы хотим вызвать метод show() из объекта obj, то команда вызова этого метода такая: obj.show(). Здесь предполагается, что методу show() при вызове аргументы не передаются (метод без аргументов). Метод show() при этом имеет автоматический доступ к полям и прочим методам объекта obj. Далее мы на конкретных примерах рассмотрим, как в программе описываются классы, создаются объекты, вызываются методы из объектов и выполняется обращение к полям объектов.

    На следующем шаге мы рассмотрим использование объектов.




Предыдущий шаг Содержание Следующий шаг