Общие сведения о классах
Типы ссылок
Тип, определенный как class
ссылочный тип. Во время выполнения при объявлении переменной ссылочного типа переменная содержит значение null
, пока явно не создадите экземпляр класса с помощью new
оператора или назначьте его объект совместимого типа, созданного в другом месте, как показано в следующем примере:
//Declaring an object of type MyClass.
MyClass mc = new MyClass();
//Declaring another object of the same type, assigning it the value of the first object.
MyClass mc2 = mc;
При создании объекта выделяется достаточный объем памяти для этого объекта в управляемой куче, и переменная хранит только ссылку на расположение данного объекта. Память, используемая объектом, освобождается функцией автоматического управления памятью среды CLR, которая называется сборкой мусора. Дополнительные сведения о сборке мусора см. в разделе Автоматическое управление памятью и сборка мусора.
Объявление классов
Классы объявляются с помощью ключевого class
слова, за которым следует уникальный идентификатор, как показано в следующем примере:
//[access modifier] - [class] - [identifier]
public class Customer
{
// Fields, properties, methods and events go here...
}
Дополнительный модификатор доступа предшествует ключевому слову class
. Доступ по умолчанию для class
типа internal
. Так как public
используется в этом случае, любой пользователь может создавать экземпляры этого класса. За именем класса следует ключевое слово class
. Имя класса должно быть допустимым именем идентификатора C#. Оставшаяся часть определения — это тело класса, в котором задаются данные и поведение. Поля, свойства, методы и события в классе собирательно называются членами класса.
Создание объектов
Хотя иногда они используются взаимозаменяемо, класс и объект отличаются. Класс определяет тип объекта, но это не сам объект. Объект — это конкретная сущность, основанная на классе, которую иногда называют экземпляром класса.
Объекты можно создать с помощью new
ключевого слова, за которым следует имя класса, как показано ниже.
Customer object1 = new Customer();
При создании экземпляра класса ссылка на объект передается программисту. В предыдущем примере object1
представляет собой ссылку на объект, который основан на Customer
. Эта ссылка ссылается на новый объект, но не содержит сами данные объекта. Фактически, можно создать ссылку на объект без создания собственно объекта:
Customer object2;
Мы не рекомендуем создавать ссылки на объекты, которые не ссылаются на объект, так как попытка доступа к объекту через такую ссылку завершается сбоем во время выполнения. Ссылка может ссылаться на объект, создав новый объект или назначив его существующему объекту, например:
Customer object3 = new Customer();
Customer object4 = object3;
В этом коде создаются две ссылки на объект, которые указывают на один и тот же объект. Таким образом, любые изменения объекта, выполненные посредством object3
, отражаются при последующем использовании object4
. Поскольку на объекты, основанные на классах, указывают ссылки, классы называют ссылочными типами.
Конструкторы и инициализация
В предыдущих разделах представлен синтаксис для объявления типа класса и создания экземпляра этого типа. При создании экземпляра типа необходимо убедиться, что его поля и свойства инициализированы в полезные значения. Существует несколько способов инициализации значений:
- Примите значения по умолчанию
- Инициализаторы полей
- Параметры конструктора
- Инициализаторы объектов
Каждый тип .NET имеет значение по умолчанию. Как правило, это значение равно 0 для типов чисел и null
для всех ссылочных типов. Вы можете полагаться на это значение по умолчанию, если оно разумно в приложении.
Если значение по умолчанию для .NET не является правильным, можно задать начальное значение с помощью инициализатора полей:
public class Container
{
// Initialize capacity field to a default value of 10:
private int _capacity = 10;
}
Для предоставления начального значения можно требовать, определив конструктор , отвечающий за настройку этого начального значения:
public class Container
{
private int _capacity;
public Container(int capacity) => _capacity = capacity;
}
Начиная с C# 12, можно определить основной конструктор в рамках объявления класса:
public class Container(int capacity)
{
private int _capacity = capacity;
}
Добавление параметров в имя класса определяет основной конструктор. Эти параметры доступны в теле класса, который включает его элементы. Их можно использовать для инициализации полей или в любом другом месте, где они необходимы.
Можно также использовать модификатор для свойства и разрешить вызывающим пользователям использовать required
инициализатор объектов, чтобы задать начальное значение свойства:
public class Person
{
public required string LastName { get; set; }
public required string FirstName { get; set; }
}
Добавление ключевого required
слова требует, чтобы вызывающие пользователи устанавливали эти свойства как часть new
выражения:
var p1 = new Person(); // Error! Required properties not set
var p2 = new Person() { FirstName = "Grace", LastName = "Hopper" };
Наследование классов
Классы полностью поддерживают наследование, фундаментальный механизм объектно ориентированного программирования. При создании класса можно наследовать от любого другого класса, который не определен как sealed
. Другие классы могут наследоваться от класса и переопределять виртуальные методы класса. Кроме того, можно реализовать один или несколько интерфейсов.
При наследовании создается производный класс, то есть класс объявляется с помощью базового класса, от которого он наследует данные и поведение. Базовый класс задается добавлением после имени производного класса двоеточия и имени базового класса, как показано далее:
public class Manager : Employee
{
// Employee fields, properties, methods and events are inherited
// New Manager fields, properties, methods and events go here...
}
Если объявление класса включает базовый класс, он наследует все члены базового класса, кроме конструкторов. Дополнительные сведения см. в разделе Наследование.
Класс в C# может непосредственно наследоваться только от одного базового класса. Однако, поскольку базовый класс может наследовать от другого класса, класс может косвенно наследовать несколько базовых классов. Кроме того, класс может напрямую реализовать несколько интерфейсов. Дополнительные сведения см. в статье Интерфейсы.
Класс можно объявить как abstract
. Абстрактный класс содержит абстрактные методы, которые имеют определение сигнатуры, но не имеют реализации. Не удается создать экземпляр абстрактных классов. Они могут использоваться только через производные классы, реализующие абстрактные методы. В отличие от этого, запечатанный класс не позволяет другим классам быть производным от него. Дополнительные сведения см. в статье Абстрактные и запечатанные классы и члены классов.
Определения классов можно разделить между различными исходными файлами. Дополнительные сведения см. в разделе Разделяемые классы и методы.
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.