ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.05.2024
Просмотров: 11
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
6.2. Классы и структуры
Классы и структуры могут содержать в себе различные элементы, например, это могут быть поля (переменные) и методы.
Рассмотрим, как объявляются классы и структуры. Для этого создадим класс для обозначения человека — Human, и структуру для обозначения животного — Animal:
class Human
{
// Поля класса
public string name;
public int age;
// Метод класса
public void Greetings()
{
Console.WriteLine("Меня зовут {0}, мне {1}", name, age);
}
}
struct Animal
{
// Поля структуры
public string type;
public string name;
public int age;
// Метод структуры
public void Info()
{
Console.WriteLine("Это {0} по кличке {1}, ему {2}", type, name, age);
}
}
При объявлении класса или структуры следует сначала написать ключевое слово class или struct, затем наименование класса (или структуры) и уже в фигурных скобках определять внутренние элементы.
В данном примере мы определили класс Human, который содержит в себе поля name и age для имени и возраста человека, а также метод Greetings, который представляет этого человека. В данном методе используются значения переменных name и age, поскольку мы имеем доступ к полям класса внутри объектов этого же класса. Ключевое слово public позволяет получать доступ к полям и методам вне данного класса (подробнее об этом поговорим позже).
Аналогично объявляем структуру Animal с полями type для типа животного (кот, собака, хомяк и т.д.), name для клички и age для возраста.
Для использования классов и структур в коде их следует использовать как типы переменных, обращаясь к ним по имени. То есть созданный выше класс Human мы можем использовать как тип переменной:
Human human;
Задание 6.2.1
Выберите корректный вариант объявления класса:
class Example
{
public string Name;
public void Show()
{
}
}
new
class Example
{
public string Name;
public void Show()
{
}
}
class Example
{
public void Name;
public void Show()
{
}
}
Расположение классов
В C# возможно определять классы (и структуры) как в пространстве имен, так и внутри других классов:
namespace FirstApp
{
class ExternalClass
{
public class ClassInternalClass
{
}
struct ClassInternalStruct
{
}
}
class ExternalStruct
{
class StructInternalClass
{
}
public struct StructInternalStruct
{
}
}
}
Внутренние классы и структуры, помеченные ключевым словом public, аналогично полям и методам, будут доступны вне используемого класса. Но только с указанием родительского класса перед наименованием используемого класса.
Например, вот так:
class Program
{
static void Main(string[] args)
{
ExternalClass.ClassInternalClass newClass;
ExternalStruct.StructInternalStruct newStruct;
}
}
Конструкторы
Помимо полей и методов классы и структуры могут содержать конструкторы.
Конструктор — специальный метод, имеющий одно название с классом (структурой), который вызывается при создании нового объекта данного класса (структуры).
Конструкторы выполняют инициализацию объекта.
Если в классе (структуре) не определен ни один конструктор, то для него автоматически создаётся конструктор по умолчанию. Такой конструктор не имеет параметров и не имеет тела.
Для класса действует правило: если в классе определен хотя бы 1 конструктор, то конструктор по умолчанию не будет создан.
Но для структуры конструктор по умолчанию будет создаваться всегда, поэтому в структуру нельзя добавить конструктор без параметров.
Инициализация переменной human с использованием конструктора будет выглядеть следующим образом:
Human human = new Human();
Оператор new выделяет память для объекта Human. И затем вызывается конструктор по умолчанию, который не принимает никаких параметров. В итоге после выполнения данного выражения в памяти будет выделен участок, где будут храниться все данные объекта Human. А переменная human получит ссылку на созданный объект.
Если конструктор не инициализирует значения полей объекта
, то они получают значения по умолчанию. Для переменных числовых типов это число 0, а для типа string и классов — это значение null (то есть фактически отсутствие значения).
Проверим это на следующем примере:
using System;
namespace FirstApp
{
class Human
{
// Поля класса
public string name;
public int age;
// Метод класса
public void Greetings()
{
Console.WriteLine("Меня зовут {0}, мне {1}", name, age);
}
}
struct Animal
{
// Поля структуры
public string type;
public string name;
public int age;
// Метод структуры
public void Info()
{
Console.WriteLine("Это {0} по кличке {1}, ему {2}", type, name, age);
}
}
class Program
{
static void Main(string[] args)
{
Human human = new Human();
human.Greetings();
human.name = "Дмитрий";
human.age = 23;
human.Greetings();
Console.ReadKey();
}
}
}
Создание конструкторов
Помимо конструктора по умолчанию пользователь может создавать свои конструкторы. Как уже говорилось ранее, конструктор — это метод, который имеет одно название с классом (структурой), для которого он определен. Определим несколько конструкторов для класса Human:
class Human
{
// Поля класса
public string name;
public int age;
// Метод класса
public void Greetings()
{
Console.WriteLine("Меня зовут {0}, мне {1}", name, age);
}
// Конструктор 1
public Human()
{
name = "Неизвестно";
age = 20;
}
// Конструктор 2
public Human(string n)
{
name = n;
age = 20;
}
// Конструктор 3
public Human(string n, int a)
{
name = n;
age = a;
}
}
Мы создали 3 конструктора:
-
Human() — конструктор без параметров; -
Human(string n) — конструктор с 1 параметром для того, чтобы присвоить имя; -
Human(string n, int a) — конструктор с 2 параметрами для имени и возраста.
Рассмотрим работу данных конструкторов:
class Program
{
static void Main(string[] args)
{
Human human = new Human();
human.Greetings();
human = new Human("Дмитрий");
human.Greetings();
human = new Human("Дмитрий", 23);
human.Greetings();
Console.ReadKey();
}
}
В конструкторе класса мы можем не инициализировать все поля. Например, мы можем оставить поле
age неинициализированным, и оно будет заполнено значением по умолчанию 0:
public Human(string n)
{
name = n;
}
Но если попробовать сделать так с конструктором структуры, мы получим ошибку:
Таким образом, в конструкторах структур нужно инициализировать все поля данной структуры.
Задание 6.2.2
Добавьте в класс Pen, указанный ниже, 2 конструктора:
-
без параметров, когда поля color и cost заполняются значениями Черный и 100. -
с 2 параметрами: penColor и penCost.
class Pen
{
public string color;
public int cost;
}
Посмотреть ответ для самопроверки
public Pen()
{
color = "Черный";
cost = 100;
}
public Pen(string penColor, int penCost)
{
color = penColor;
cost = penCost;
}
Инициализаторы
Помимо явного вызова конструкторов для инициализации объектов можно воспользоваться инициализаторами.
Инициализаторы представляют передачу в фигурных скобках значений доступным полям и свойствам объекта.
Например, при выполнении следующего кода:
Human human = new Human { name = "Дмитрий", age = 23 };
human.Greetings();
В консоль будет выведено сообщение: Меня зовут Дмитрий, мне 23. Таким образом, при создании объекта неявно будет вызван конструктор, и после этого поля name и age будут заполнены значениями.
Важно отметить:
-
С помощью инициализатора можно устанавливать значения только доступных из внешнего кода полей и свойств объекта (которые помечены ключевым словом public). -
Если в конструкторе устанавливаются значения полей, которые указаны в инициализаторе, то значения, устанавливаемые в конструкторе, заменяются значениями из инициализатора.
Назначение структур
Как вы уже поняли, по представленному функционалу структуры и классы не так уж сильно и отличаются. Однако, отличия будут вскрываться далее, при погружении в ООП.
Структуры работают быстрее из-за различия в хранении данных. Но они очень узконаправлены, и использовать их стоит, когда экземпляры структуры малы, недолго «живут» и часто используются внутри других типов.
Если тип имеет не все нижеприведенные характеристики, Microsoft не советует пользоваться структурой:
-
Тип представляет одно простое значение, схожее с примитивными типами. -
Размер экземпляра не более 16 байт. -
Значение неизменяемо. -
Тип будет часто упаковываться (об упаковке читайте в следующем юните).
Подробнее можете прочитать в следующей статье.
Задание 6.2.8
Создайте класс Rectangle для представления прямоугольников удовлетворяющий следующим требованиям:
-
Класс должен содержать целочисленные поля для сторон a и b. -
Класс должен содержать метод Square, возвращающий площадь прямоугольника (произведение сторон). -
Класс должен содержать 3 конструктора: с 2 параметрами, когда a != b, с 1 параметром, когда a == b, и конструктор без параметров по умолчанию, в котором стороны будут заполняться как a = 6, b = 4. -