Теперь, когда вы знаете о роли Main(), перейдем в задаче построения объектов. Во всех объектно-ориентированных языках делается четкое различие между классами и объектами. Термин класс используется для определения пользовательского типа (User-Defined Type – UDT) , или, если хотите, шаблона . А термин объект применяется для обозначения экземпляра конкретного класса в памяти. Ключевое слово new в C# обеспечивает способ создания объектов. В отличие от других объектно-ориентированных языков (таких как, например, C++), в C# невозможно разместить тип класса в стеке, поэтому если вы попытаетесь использовать переменную класса, которая не была создана с помощью new, вы получите ошибку компиляции. Таким образом, следующий программный код C# оказывается недопустимым .
using System;
class HelloClass {
public static int Main(string[] args) {
// Ошибка! Используется неинициализированная локальная
// переменная. Следует использовать 'new'.
HelloClass c1;
с1.SomeMethod();
…
}
}
Чтобы использовать правильные процедуры для создания объектов, внесите следующие изменения.
using System;
class HelloClass {
public static int Main(string[] args) {
// Можно объявить и создать объект в одной строке…
HelloClass с1 = newHelloClass();
//…или указать объявление и создание в разных строках.
HelloClass c2;
с2 = newHelloClass();
…
}
}
Ключевое слово new отвечает за вычисление числа байтов, необходимых для заданного объекта, и выделение достаточного объема управляемой динамической памяти (managed heap). В данном случае вы размещаете два объекта типа класса HelloClass. Следует понимать, что объектные переменные C# на самом деле являются ссылками на объект в памяти, а не фактическими объектами. Так что c1 и с2 ссылаются на уникальный объект HelloClass, размещенный а управляемой динамической памяти.
До сих пор объекты HelloClass строились с помощью конструктора, заданного по умолчанию, который, по определению, не имеет аргументов. Каждый класс C# автоматически снабжается типовым конструктором, который вы можете при необходимости переопределить. Этот типовой конструктор используется по умолчанию и гарантирует, что все члены-данные по умолчанию получат подходящие типовые значения (такое поведение характерно для всем конструкторов). Сравните это с ситуацией в C++. где неинициализированные данные указывают на "мусор" (иногда мелочи оказываются очень важными).
Обычно кроме конструктора, заданного по умолчанию, классы предлагают и другие конструкторы. Тем самым вы обеспечиваете возможность инициализации состояния объекта во время его создания, Подобно Java и C++, конструкторы в C# имеют имя, соответствующее имени класса, который они конструируют, и они никогда не возвращают значения (даже значения void). Ниже снова рассматривается тип HelloClass, но с пользовательским конструктором, переопределенным заданным по умолчанию конструктором, и элементом открытых строковых данных.
// HelloClass c конструкторами.
class HelloClass {
// Элемент открытых данных.
public string userMessage;
// Конструктор, заданный по умолчанию.
public HelloClass() {
Console.WriteLine("Вызван конструктор, заданный по умолчанию!");
}
// Пользовательский конструктор, связывающий данные состояния
// с данными пользователя.
public HelloClass(string msg) {
Console.WriteLine("Вызван пользовательский конструктор!");
userMessage = msg;
}
// точка входа программы.
public static int Main(string[] args) {
// Вызов конструктора, заданного по умолчанию
HelloClass c1 = new HelloClass();
Console.WriteLine("Значение userMessage: {0}\n", c1.userMessage);
// Вызов параметризованного конструктора
HelloClass c2;
c2 = new HelloClass("Проверка. 1, 2, 3"); Console.WriteLine("Значение userMessage: {0}\n ", c2.userMessage);
Console.ReadLine();
return 0;
}
}
Замечание. Если тип определяет члены (включая и конструкторы) с одинаковыми именами, которые отличаются только числом (или типом) параметров, то соответствующий член называют перегруженным. В главе 4 перегрузка будет рассмотрена подробно.
При анализе вывода этой (программы можно заметить что конструктор, заданный по умолчанию, присваивает строковому полю значение (пустое), предусмотренное по умолчанию, в то время как специальный конструктор определяет для члена значение, предоставленное пользователем (pиc. 3.4).
Читать дальше