Опубликован: 25.09.2008 | Доступ: свободный | Студентов: 3223 / 516 | Оценка: 4.32 / 3.98 | Длительность: 18:50:00
ISBN: 978-5-94774-991-5
Лекция 3:

Основы языка C#

Классы и структуры

Классы

Не претендуя на полноту изложения положений объектно-ориентированного анализа и проектирования, постараемся разобрать один из аспектов практического применения его принципов. За дополнительной информацией относительно особенностей объектного программирования в C# рекомендуется обращаться к [ 3 ] .

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

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

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

Все современные программные системы создаются с использованием принципов объектно-ориентированного программирования. Это означает, что любая сущность, с которой осуществляются какие-либо действия, должна быть описана в виде класса. Таким образом, система представляет собой совокупность взаимодействующих друг с другом классов. Определение класса в C# практически идентично определению такого же класса в C++. Тем не менее в C# существуют дополнительные элементы, значительно облегчающие практическое использование классов. Рассмотрим основные правила и примеры построения и использования классов.

Предполагая, что читатель знаком с основами объектного программирования на C++, рассмотрим пример создания и использования классов с помощью языка C#.

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

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

public class Client
{
  private string Name;
  private string Passport;
  private DateTime BirthDate;

  public Client()
  {

  }
}

Здесь определены поля класса, а также конструктор по умолчанию (без параметров). Для классов C# можно определить любое количество конструкторов. Если в классе не определен ни один конструктор, используется конструктор по умолчанию, который при создании объекта автоматически присвоит всем переменным - членам класса безопасные значения. В данном случае, конструктор по умолчанию задается явно.

Область видимости полей класса в соответствии с правилами должна быть определена либо как закрытая, либо как защищенная (в случае, если предполагается наследование его полей). Доступ же к полям - членам класса должен быть организован либо посредством методов, либо с помощью свойств класса. Ранее в языке C++ свойства отсутствовали, однако они позволяют организовывать очень простой доступ к полям - членам класса. Создадим свойства класса Client, обеспечивающие чтение и запись значений полей класса.

public string passport
{
  get
  {
    return Passport;
  }
  set
  {
    Passport = value;
  }
}

public string name
{
  get
  {
    return Name;
  }
  set
  {
    Name = value;
  }
}

public int age
{
  get
  {
    int a;
    a = DateTime.Now.Year - BirthDate.Year;
    return a;
  }
}

public DateTime birthdate
{
  get
  {
    return BirthDate;
  }
  set
  {
    if (DateTime.Now > value)
      BirthDate = value;
    else
      throw new Exception("Введена неверная дата рождения");
  }
}

Как видно из данного примера, свойство состоит из методов set и get. При этом свойство должно содержать хотя бы один из методов. Set позволяет изменять значение поля класса, get - получать значение. В метод Set передается значение параметра с помощью переменной value. Оба метода могут содержать произвольное количество операторов, описывающих алгоритм выполнения действий в процессе чтения или записи значения в поле класса. В данном примере свойства passport и name позволяют просто получить доступ к полям класса, считывая или устанавливая значения соответствующих переменных. Свойство birthdate также предназначено для чтения и записи значения переменной - члена класса BirthDate. При этом при чтении значения (операция get ) происходит просто передача значения переменной BirthDate, при попытке же записи нового значения в эту переменную происходит проверка допустимости устанавливаемого значения переменной. В данном случае проверка сводится к сравнению нового значения даты рождения с текущей датой. Если устанавливаемое значение даты рождения больше либо равно текущей дате, генерируется исключение, которое не позволяет записать новое значение в переменную - член класса.

Свойство age применяется для получения текущего возраста клиента. Оно предназначено только для чтения значения из переменной, поэтому содержит лишь метод get. При использовании свойства age происходит вычисление текущего значения возраста клиента в годах путем вычитания года рождения из текущего значения года.

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

Client c1=new Client();
c1.name = "Вася";
c1.passport = "9002";
c1.birthdate = new DateTime(1967, 08, 03);
Response.Write("Имя=" + c1.name+"</br>");
Response.Write("Паспорт=" + c1.passport+"</br>");
Response.Write("Возраст="+c1.age);

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

public Client(string ClientName, string ClientPassport,
DateTime ClientBirthDate)
{
  name = ClientName;
  passport = ClientPassport;
  birthdate = ClientBirthDate;
}

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

Создадим также метод, позволяющий изменить значения полей объекта класса Client:

public void EditClient(string ClientName, string
 ClientPassport,DateTime ClientBirthDate)
{
  Name = ClientName;
  Passport = ClientPassport;
  birthdate = ClientBirthDate;
}

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

Теперь, с использованием конструктора с параметрами, можно создать и сразу же инициализировать объект класса Client:

Client c1=new Client("Вася","9002",new DateTime(1967,08,03));