Конструкторы экземпляра класса и статические члены класса 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Конструкторы экземпляра класса и статические члены класса



 

Как уже говорилось выше, в C# конструкторы вызываются при создании объекта (конструктор экземпляра) или когда CLR загружает тип (статический конструктор). У каждого класса по умолчанию всегда есть конструктор, даже если он не описан явно. Например:

 

class MyClass

{

}

 

class MyClass

{

public MyClass()

{

}

}

 

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

 

Конструкторы могут быть перегружены и принимать параметры:

 

class MyClass

{

public MyClass()

{

// Выполнили действия по инициализации

}

 

public MyClass(int x)

{

// Выполнили действия по инициализации

}

}

 

В примере выше у класса есть два конструктора, один пустой (так называемый конструктор по умолчанию), другой принимает целочисленное значение, которые может быть использовано.

 

Конструкторы экземпляра срабатывают при создании нового объекта:

 

MyClass cl = new MyClass();

MyClass ck = new MyClass(1);

 

В первом случае сработал конструктор без аргументов, во втором, в качестве аргумента была передана единица. Всё описанное выше относится к конструкторам экземпляра.

 

В случае, когда экземпляр класса не создаётся, но всё же требуется вызвать конструктор и произвести какие-то действия, используется статический конструктор (static) для статических членов класса:

 

class MyClass

{

static MyClass()

{

// Выполнили действия по инициализации

// Этот конструктор не обязательно описывать, если он не нужен

}

 

public static int Sum(int x, int y)

{

return x + y;

}

}

 

В этом случае конструктор сработает при первом обращении к типу.

 

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

 

public class Automobile

{

public static int NumberOfWheels = 4;

public static int SizeOfGasTank

{

get

{

return 15;

}

}

public static void Drive() { }

public static event EventType RunOutOfGas;

 

// Прочие статические и нестатические члены класса

}

 

Однако существуют небольшие и существенные отличия статического конструктора от обычного конструктора. Статический конструктор:

  • не требует модификаторов доступа и не может принимать параметры. Т. е. используется только так, как описано в примере выше;
  • вызывается при создании первого экземпляра;
  • нет возможности вызывать статический конструктор напрямую;
  • вызывается только один раз, в независимости, сколько экземпляров было создано и остаётся в памяти домена приложения до закрытия программы;
  • может быть описан в классе только один раз;
  • если в классе есть конструктор экземпляра, то статический конструктор вызовется раньше конструктора экземпляра;
  • статический конструктор может быть использован только для инициализации статических данных или выполнения каких-то действий (например, запись в строковую переменную, что был выполнен доступ к текущему классу).

 

int sum = MyClass.Sum(3, 2);

 

В результате переменная sum будет содержать значение 5 и в тоже время, выполнится код в конструкторе public static MyClass() до выполнения метода Sum. Другими словами, любой конструктор выполнится, до того момента, когда будут использоваться возможности класса. Как можно заметить, все конструкторы отмечаются как public, что делает возможность создавать экземпляры с помощью оператора new. Если вместо public, написать private, то таким образом закроется возможность создавать новые экземпляры (будет вызван закрытый конструктор). Чаще всего эта возможность используется, когда класс содержит только статические свойства и методы.

Существуют ещё два модификатора: protected и internal. Если член класса имеет модификатор public, то, как уже говорилось выше, к нему можно обращаться из любого места программы через точку. Если private, то только в пределах данного класса. Protected — запрещает использование члена в классе-наследнике. Internal — служит для ограничения области видимости в пределах нескольких сборок. Открытым интерфейсом называется совокупность типов имеющих модификатор public.

Для самих классов доступно только два модификатора: public и internal. Их действие аналогично действиям для членов класса.

 

Такой вот код вызовет ошибку:

 

class MyClass

{

static MyClass()

{

//Выполнили действия по инициализации

//Этот конструктор не обязательно описывать, если он не нужен

}

 

private MyClass()

{

//Никогда не вызовется

}

 

public static int Sum(int x, int y)

{

return x + y;

}

}

...

private void button1_Click(object sender, EventArgs e) // Пусть это будет нажатие кнопки button1 на форме

{

MyClass cl = new MyClass(); // Неправильно (вызовет ошибку, нельзя создать экземпляр класса из-за уровня защиты private)

int sum = MyClass.Sum(3,2); // Правильно (вызываем статический метод из нестатического класса)

MessageBox.Show(sum.ToString());

}

 

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

 

Понятие «Статический класс»

 

Статический класс в основном такой же, что и нестатический класс, но имеется одно отличие: нельзя создавать экземпляры статического класса. Другими словами, нельзя использовать ключевое слово new для создания переменной типа класса. Поскольку нет переменной экземпляра, доступ к членам статического класса осуществляется с использованием самого имени класса. Например, если имеется статический класс, называемый UtilityClass, имеющий открытый метод, называемый MethodA, вызов метода выполняется, как показано в следующем примере:

 

UtilityClass.MethodA();

 

Статический класс может использоваться как обычный контейнер для наборов методов, работающих на входных параметрах, и не должен возвращать или устанавливать каких-либо внутренних полей экземпляра. Например, в библиотеке классов платформы.NET Framework статический класс System.Math содержит методы, выполняющие математические операции, без требования сохранять или извлекать данные, уникальные для конкретного экземпляра класса Math. Это значит, что члены класса применяются путём задания имени класса и имени метода, как показано в следующем примере консольного приложения:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

//using System.Math;

 

namespace LC_Console

{

class Program

{

static void Main(string[] args)

{

double dub = -3.14;

Console.WriteLine(Math.Abs(dub));

Console.WriteLine(Math.Floor(dub));

Console.WriteLine(Math.Round(Math.Abs(dub)));

/* Выведет:

* 3.14

* -4

* 3

*/

}

}

}

 

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

 

Следующий список предоставляет основные характеристики статического класса:

  • Содержит только статические члены.
  • Создавать его экземпляры нельзя.
  • Он закрыт.
  • Не может содержать конструкторов экземпляров.

 

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

Статические классы запечатаны, поэтому их нельзя наследовать. Они не могут быть унаследованы ни от каких классов, кроме Object. Статические классы не могут содержать конструктор экземпляров, но могут содержать статический конструктор. Нестатические классы, как уже говорилось выше, также должен определять статический конструктор, если класс содержит статические члены, для которых нужна нетривиальная инициализация.

 

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

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace LC_Console

{

public static class TemperatureConverter

{

public static double CelsiusToFahrenheit(string temperatureCelsius)

{

// Преобразуем аргумент в тип double для подсчёта

double celsius = Double.Parse(temperatureCelsius);

// Из Цельсий в ФаренгейтыConvert Celsius to Fahrenheit.

double fahrenheit = (celsius * 9 / 5) + 32;

return fahrenheit;

}

 

public static double FahrenheitToCelsius(string temperatureFahrenheit)

{

double fahrenheit = Double.Parse(temperatureFahrenheit);

double celsius = (fahrenheit - 32) * 5 / 9;

return celsius;

}

}

 

class TestTemperatureConverter

{

static void Main()

{

Console.WriteLine("Пожалуйста, выберите направления конвертирования");

Console.WriteLine("1. Из Цельсий в Фаренгейты.");

Console.WriteLine("2. Из Фаренгейтов в Цельсии.");

Console.Write(":");

 

string selection = Console.ReadLine();

double F, C = 0;

 

switch (selection)

{

case "1":

Console.Write("Укажите температуру по Цельсию: ");

F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine());

Console.WriteLine("Температура в градусах Фаренгейта: {0:F2}", F);

break;

case "2":

Console.Write("Укажите температура по Фаренгейту: ");

C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine());

Console.WriteLine("Температура в градусах Цельсия: {0:F2}", C);

break;

default:

Console.WriteLine("Пожалуйста, выберите направления конвертирования.");

break;

}

 

// Keep the console window open in debug mode.

Console.WriteLine("Для продолжения нажмите любую клавишу...");

Console.ReadKey();

}

}

}

/* Выведет если ввести цифру 2 во время выполнения:

* Пожалуйста, выберите направления конвертирования

* 1. Из Цельсий в Фаренгейты.

* 2. Из Фаренгейтов в Цельсии.

*:2

* Укажите температура по Фаренгейту: 20

* Температура в градусах Цельсия: -6.67

* Для продолжения нажмите любую клавишу...

*/

 



Поделиться:


Последнее изменение этой страницы: 2016-08-15; просмотров: 365; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.189.2.122 (0.044 с.)