Что такое статический класс
Перейти к содержимому

Что такое статический класс

  • автор:

Зачем нужен static class?

Статические переменные нужны для доступа к ним, без создания экземпляра класса. А вот зачем нужен static класс?

Отслеживать
123k 24 24 золотых знака 128 128 серебряных знаков 307 307 бронзовых знаков
задан 18 ноя 2016 в 9:31
2,168 2 2 золотых знака 15 15 серебряных знаков 36 36 бронзовых знаков

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

Статическим классом в java может быть только вложенный класс. Если класс отмечен как static, то он ведет себя, как обычный класс.

например, есть класс А, вложенный статический класс B и вложенный (нестатический) класс С:

public class A < . static public class B< >public class C < >> 

и мы хотим создать экземпляры этих классов во «внешнем» коде

public class Test < public static void main(String[] args) < A a = new A(); // обычный класс A.B b = new A.B(); // статический вложенный класс A.C c = a.new C(); // вложенный класс, связан с экземпляром А // A.C c = new A.C(); // синтаксическая ошибка (не скомпилится) >> 

или внутри статических методов класса А

public class A < . static public class B< >public class C < >public static void main(String[] args) < A a = new A(); // обычный класс A.B b = new A.B(); // статический вложенный класс A.C c = a.new C(); // вложенный класс, связан с экземпляром А // A.C c = new A.C(); // синтаксическая ошибка (не скомпилится) >public static void test() < A a = new A(); // обычный класс A.B b = new A.B(); // статический вложенный класс A.C c = a.new C(); // вложенный класс, связан с экземпляром А // A.C c = new A.C(); // синтаксическая ошибка (не скомпилится) >> 

На мой взгляд использование статического класса может быть уместно, как небольшой класс, который по смыслу тесно связан с «основным» внешним классом.

public class Tree < static public class Node< >> 

В этой ситуации так же можно вынести вложенный класс в обычный и переместить оба класса в отдельный package.

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

public class A < private void privateMethod()< B b = new B(); b.privateMethod(); // есть доступ к приватным методам/полям >static public class B < private void privateMethod()< A a = new A(); a.privateMethod(); // есть доступ к приватным методам/полям >> > 

Что такое статический класс

Кроме обычных полей, методов, свойств классы и структуры могут иметь статические поля, методы, свойства. Статические поля, методы, свойства относятся ко всему классу/всей структуре и для обращения к подобным членам необязательно создавать экземпляр класса / структуры.

Статические поля

Статические поля хранят состояние всего класса / структуры. Статическое поле определяется как и обычное, только перед типом поля указывается ключевое слово static . Например, рассмотрим класс Person, который представляет человека:

Person bob = new(68); bob.СheckAge(); // Уже на пенсии Person tom = new(37); tom.СheckAge(); // Сколько лет осталось до пенсии: 28 // получение статического поля Console.WriteLine(Person.retirementAge); // 65 // изменение статического поля Person.retirementAge = 67; class Person < int age; public static int retirementAge = 65; public Person(int age) < this.age = age; >public void СheckAge() < if (age >= retirementAge) Console.WriteLine("Уже на пенсии"); else Console.WriteLine($"Сколько лет осталось до пенсии: "); > >

В данном случае класс Person имеет два поля: age (хранит возраст человека) и retirementAge (хранит пенсионный возраст). Однако поле retirementAge является статическим. Оно относится не к конкретному человеку, а ко всем людям. (В данном случае для упрощения пренебрежем тем фактом, что в зависимости от пола и профессии пенсионный возраст может отличаться.) Таким образом, поле retirementAge относится не к отдельную объекту и хранит значение НЕ отдельного объекта класса Person, а относится ко всему классу Person и хранит общее значение для всего класса.

Причем в самом классе мы можем использовать это поле как и любые другие. Так, в методе СheckAge() , который поверяет пенсионный статус человека, для проверки используем это поле:

if (age >= retirementAge)

Но если мы хотим обратиться к этому полю вне своего класса, то мы можем обращаться к этому полю по имени класса:

Console.WriteLine(Person.retirementAge); Person.retirementAge = 67;

На уровне памяти для статических полей будет создаваться участок в памяти, который будет общим для всех объектов класса.

Статические методы класса в C#

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

Статические свойства

Подобным образом мы можем создавать и использовать статические свойства:

Person bob = new(68); bob.СheckAge(); Console.WriteLine(Person.RetirementAge); // 65 class Person < int age; static int retirementAge = 65; public static int RetirementAge < get < return retirementAge; >set < if (value >1 && value < 100) retirementAge = value; >> public Person(int age) < this.age = age; >public void СheckAge() < if (age >= retirementAge) Console.WriteLine("Уже на пенсии"); else Console.WriteLine($"Сколько лет осталось до пенсии: ") ; > >

В данном случае доступ к статической переменной retirementAge опосредуется с помощью статического свойства RetirementAge .

Таким образом, переменные и свойства, которые хранят состояние, общее для всех объектов класса / структуры, следует определять как статические.

Нередко статические поля и свойства применяются для хранения счетчиков. Например, мы хотим иметь счетчик, который позволял бы узнать, сколько объектов Person создано:

var tom = new Person(); var bob = new Person(); var sam = new Person(); Console.WriteLine(Person.Counter); // 3 class Person < static int counter = 0; public static int Counter =>counter; public Person() < counter++; >>

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

Статические методы

Статические методы определяют общее для всех объектов поведение, которое не зависит от конкретного объекта. Для обращения к статическим методам также применяется имя класса / структуры:

Person bob = new(68); Person.CheckRetirementStatus(bob); class Person < public int Age < get; set; >static int retirementAge = 65; public Person(int age) => Age = age; public static void CheckRetirementStatus(Person person) < if (person.Age >= retirementAge) Console.WriteLine("Уже на пенсии"); else Console.WriteLine($"Сколько лет осталось до пенсии: ") ; > >

В данном случае в классе Person определен статический метод CheckRetirementStatus() , который в качестве параметра принимает объект Person и проверяет его пенсионный статус.

Следует учитывать, что статические методы могут обращаться только к статическим членам класса. Обращаться к нестатическим методам, полям, свойствам внутри статического метода мы не можем.

Статический конструктор

Кроме обычных конструкторов у класса также могут быть статические конструкторы. Статические конструкторы имеют следующие отличительные черты:

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

Статические конструкторы обычно используются для инициализации статических данных, либо же выполняют действия, которые требуется выполнить только один раз

Определим статический конструктор:

Console.WriteLine(Person.RetirementAge); class Person < static int retirementAge; public static int RetirementAge =>retirementAge; static Person() < if (DateTime.Now.Year == 2022) retirementAge = 65; else retirementAge = 67; >>

В данном случае с помощью встроенной структуры DateTime получаем текущий год. Для этого используется свойство DateTime.Now.Year . если он равен 2022, устанавливаем один пенсионный возраст. При другом значении текущего года устанавливается другое значение пенсионного возраста.

Статические классы

Статические классы объявляются с модификатором static и могут содержать только статические поля, свойства и методы. Например, определим класс, который выполняет ряд арифметических операций:

Console.WriteLine(Operations.Add(5, 4)); // 9 Console.WriteLine(Operations.Subtract(5, 4)); // 1 Console.WriteLine(Operations.Multiply(5, 4)); // 20 static class Operations < public static int Add(int x, int y) =>x + y; public static int Subtract(int x, int y) => x - y; public static int Multiply(int x, int y) => x * y; >

Как создать статический класс java

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

Для создания статического класса в Java , нужно использовать ключевое слово static при определении класса внутри другого класса. Например:

public class OuterClass  // код внешнего класса static class StaticNestedClass  // код статического вложенного класса > > 

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

Статические классы и члены статических классов (Руководство по программированию в C#)

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

UtilityClass.MethodA(); 

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

double dub = -3.14; Console.WriteLine(Math.Abs(dub)); Console.WriteLine(Math.Floor(dub)); Console.WriteLine(Math.Round(Math.Abs(dub))); // Output: // 3.14 // -4 // 3 

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

Создание нестатического класса, который допускает создание только одного экземпляра самого себя, см. в документе Реализация Singleton в C#.

Ниже приведены основные возможности статического класса.

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

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

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

Пример

Ниже приведен пример статического класса, содержащего два метода, преобразующих температуру по Цельсию в температуру по Фаренгейту и наоборот.

public static class TemperatureConverter < public static double CelsiusToFahrenheit(string temperatureCelsius) < // Convert argument to double for calculations. double celsius = Double.Parse(temperatureCelsius); // Convert Celsius to Fahrenheit. double fahrenheit = (celsius * 9 / 5) + 32; return fahrenheit; >public static double FahrenheitToCelsius(string temperatureFahrenheit) < // Convert argument to double for calculations. double fahrenheit = Double.Parse(temperatureFahrenheit); // Convert Fahrenheit to Celsius. double celsius = (fahrenheit - 32) * 5 / 9; return celsius; >> class TestTemperatureConverter < static void Main() < Console.WriteLine("Please select the convertor direction"); Console.WriteLine("1. From Celsius to Fahrenheit."); Console.WriteLine("2. From Fahrenheit to Celsius."); Console.Write(":"); string? selection = Console.ReadLine(); double F, C = 0; switch (selection) < case "1": Console.Write("Please enter the Celsius temperature: "); F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine() ?? "0"); Console.WriteLine("Temperature in Fahrenheit: ", F); break; case "2": Console.Write("Please enter the Fahrenheit temperature: "); C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine() ?? "0"); Console.WriteLine("Temperature in Celsius: ", C); break; default: Console.WriteLine("Please select a convertor."); break; > // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); > > /* Example Output: Please select the convertor direction 1. From Celsius to Fahrenheit. 2. From Fahrenheit to Celsius. :2 Please enter the Fahrenheit temperature: 20 Temperature in Celsius: -6.67 Press any key to exit. */ 

Статический члены

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

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

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

Несмотря на то, что поле не может быть объявлено как static const , поле const по своему поведению является статическим. Он относится к типу, а не к экземплярам типа. Поэтому к полям const можно обращаться с использованием той же нотации ClassName.MemberName , что и для статических полей. Экземпляр объекта не требуется.

C# не поддерживает статические локальные переменные (то есть переменные, объявленные в области действия метода).

Для объявления статических методов класса используется ключевое слово 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; // Other non-static fields and properties. > 

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

Automobile.Drive(); int i = Automobile.NumberOfWheels; 

Если класс содержит статические поля, должен быть указан статический конструктор, который инициализирует эти поля при загрузке класса.

Вызов статического метода генерирует инструкцию вызова в промежуточном языке Microsoft (MSIL), в то время как вызов метода экземпляра генерирует инструкцию callvirt , которая также проверяет наличие ссылок на пустые объекты. Однако в большинстве случаев разница в производительности двух видов вызовов несущественна.

Спецификация языка C#

Дополнительные сведения см. в разделе Статические классы, статические члены и члены экземпляра и статические конструкторы в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

См. также

  • Руководство по программированию на C#
  • static
  • Классы
  • class
  • Статические конструкторы
  • Конструкторы экземпляров

Совместная работа с нами на GitHub

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *