Классы и объекты


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

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

В принципе ранее уже использовались классы. Например, тип string, который представляет строку, фактически является классом. Или, например, класс Console, у которого метод WriteLine() выводит на консоль некоторую информацию. Теперь же посмотрим, как мы можем определять свои собственные классы.

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

class название_класса
{
// содержимое класса
}
После слова class идет имя класса и далее в фигурных скобках идет собственно содержимое класса. Например, определим в файле Program.cs класс Person, который будет представлять человека:

class Person
{

}
Классы и объекты в языке программирования C# и .NET
Однако такой класс не особо показателен, поэтому добавим в него некоторую функциональность.

Поля и методы класса
Класс может хранить некоторые данные. Для хранения данных в классе применяются поля. По сути поля класса - это переменные, определенные на уровне класса.

Кроме того, класс может определять некоторое поведение или выполняемые действия. Для определения поведения в классе применяются методы.

Итак, добавим в класс Person поля и методы:

class Person
{
public string name = "Undefined"; // имя
public int age; // возраст

public void Print()
{
Console.WriteLine($"Имя: {name} Возраст: {age}");
}
}
В данном случае в классе Person определено поле name, которое хранит имя, и поле age, которое хранит возраст человека. В отличие от переменных, определенных в методах, поля класса могут иметь модификаторы, которые указываются перед полем. Так, в данном случае, чтобы все поля были доступны вне класса Person поля определены с модификатором public.

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

Также в классе Person определен метод Print(). Методы класса имеют доступ к его поля, и в данном случае обращаемся к полям класса name и age для вывода их значения на консоль. И чтобы этот метод был виден вне класса, он также определен с модификатором public.

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

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

Конструктор по умолчанию
Если в классе не определено ни одного конструктора (как в случае с нашим классом Person), то для этого класса автоматически создается пустой конструктор по умолчанию, который не принимает никаких параметров.

Теперь создадим объект класса Person:

Person tom = new Person(); // создание объекта класса Person

// определение класса Person
class Person
{
public string name = "Undefined";
public int age;

public void Print()
{
Console.WriteLine($"Имя: {name} Возраст: {age}");
}
}
создание классов в языке программирования C# и .NET
Для создания объекта Person используется выражение new Person(). В итоге после выполнения данного выражения в памяти будет выделен участок, где будут храниться все данные объекта Person. А переменная tom получит ссылку на созданный объект, и через эту переменную мы можем использовать данный объект и обращаться к его функциональности.

Обращение к функциональности класса
Для обращения к функциональности класса - полям, методам (а также другим элементам класса) применяется точечная нотация точки - после объекта класса ставится точка, а затем элемент класса:

объект.поле_класса
объект.метод_класса(параметры_метода)
Например, обратимся к полям и методам объекта Person:

Person tom = new Person(); // создание объекта класса Person

// Получаем значение полей в переменные
string personName = tom.name;
int personAge = tom.age;
Console.WriteLine($"Имя: {personName} Возраст {personAge}"); // Имя: Undefined Возраст: 0

// устанавливаем новые значения полей
tom.name = "Tom";
tom.age = 37;

// обращаемся к методу Print
tom.Print(); // Имя: Tom Возраст: 37

class Person
{
public string name = "Undefined";
public int age;

public void Print()
{
Console.WriteLine($"Имя: {name} Возраст: {age}");
}
}
Консольный вывод данной программы:

Имя: Undefined Возраст: 0
Имя: Tom Возраст: 37
Константы классы
Кроме полей класс может определять для хранения данных константы. В отличие от полей из значение устанавливается один раз непосредственно при их объявлении и впоследствии не может быть изменено. Кроме того, константы хранят некоторые данные, которые относятся не к одному объекту, а ко всему классу в целом. И для обращения к константам применяется не имя объекта, а имя класса:

Person tom = new Person();
tom.name = "Tom";
tom.age = 37;
tom.Print(); // Person: Tom - 37

Console.WriteLine(Person.type); // Person
// Person.type = "User"; // !Ошибка: изменить константу нельзя

class Person
{
public const string type = "Person";
public string name = "Undefined";
public int age;
public void Print() => Console.WriteLine($"{type}: {name} - {age}");
}
Здесь в классе Person определена константа type, которая хранит название класса:

public const string type = "Person";
Название класса не зависит от объекта. Мы можем создать много объектов Person, но название класса от этого не должно измениться - оно относится ко всем объектам Person и не должно меняться. Поэтому название типа можно сохранить в виде константы.

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

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

Однако если мы хотим обратиться к константе вне ее класса, то для обращения необходимо использовались имя класса:

Console.WriteLine(Person.type); // Person
Таким образом, если необходимо хранить данные, которые относятся ко всему классу в целом, то можно использовать константы.

Добавление класса в Visual Studio
Обычно классы помещаются в отдельные файлы. Нередко для одного класса предназначен один файл. И Visual Studio предоставляет по умолчанию встроенные шаблоны для добвления класса.

Для добавления класса нажмем в Visual Studio правой кнопкой мыши на название проекта:

Добавление класса в Visual Studio в C#
В появившемся контекстном меню выберем пункт Add -> New Item... (или Add -> Class...)

В открывшемся окне добавления нового элемента убедимся, что в центральной части с шаблонами элементов у нас выбран пункт Class. А внизу окна в поле Name введем название добавляемого класса - пусть он будет назваться Person:

Добавление нового класса в Visual Studio в C#
В качестве названия класса можно вводить как Person, так и Person.cs. И после нажатия на кнопку добавления в проект будет добавлен новый класс:

Добавление класса в проект в Visual Studio в C#
В файле Person.cs определим следующий код:

class Person
{
public string name = "Undefined";
public void Print()
{
Console.WriteLine($"Person {name}");
}
}
Здесь определен класс Person с одним полем name и методом Print.

В файле Program.cs, который представляет основной файл программы используем класс Person:

Person tom = new Person();
tom.name = "Tom";
tom.Print(); // Person Tom
Использование классов в проекте в Visual Studio в языке программирования C#
Таким образом, мы можем определять классы в отдельных файлах и использовать их в программе.