Васильев А.Н. Основы программирования на C#. Васильев А. Н. Программирование
Скачать 5.54 Mb.
|
Результат выполнения программы (из листинга 3.8) Ɇɚɫɫɢɜ: |A|l|p|h|a| ɑɢɫɥɨɜɨɟ ɩɨɥɟ: 100 Ɇɚɫɫɢɜ: |B|r|a|v|o| ɑɢɫɥɨɜɨɟ ɩɨɥɟ: Структура MyStruct имеет поле name, являющееся ссылкой на символьный массива также в структуре есть целочисленное поле code. Глава Конструктор в структуре описан так, что новый экземпляр может создаваться на основе ссылки на символьный массив и целочисленного значения. Они передаются аргументами конструктору и определяют значения полей экземпляра. Также в структуре описан метод show(), который при вызове отображает в консольном окне содержимое символьного массива и значение числового поля. В классе с главным методом описан еще и статический метод create(), который возвращает результатом экземпляр структуры MyStruct, а аргументами методу передаются текстовое и целочисленное значения. В теле метода командой char[] s=t.ToCharArray() на основе текстового аргумента t создается символьный массив s, и затем этот символьный массив передается аргументом конструктору в команде, которой создается экземпляр R структуры MyStruct. Командой return R экземпляр структуры возвращается результатом метода. В главном методе командой MyStruct A создаем экземпляр структуры, а затем командой A=create( ƎAlphaƎ,100) этому экземпляру в качестве значения присваивается результат вызова метода create(). Что происходит в этом случае При вызове метода create(), в соответствии с переданными методу аргументами, создается экземпляр структуры. Этот экземпляр присваивается в качестве значения переменной A. Происходит побитовое копирование значений полей. После этого у экземпляра поля будут иметь такие же значения, как у экземпляра, вычисленного при вызове метода create(). Проверяем это с помощью команды A.show(). q ПОДРОБНО СТ ИВ структуре MyStruct есть поле, представляющее собой ссылку на массив. Когда при вызове метода create() создается экземпляр структуры, то создается и массивна который ссылается поле name этого экземпляра. Экземпляр возвращается в качестве результата метода. Обычно результат метода присваивается какой-то переменной. В таком случае происходит побитовое копирование значений полей. Для поля, являющегося ссылкой на массив, копируется ссылка. Получается, что и экземпляр, являющийся результатом метода, и экземпляр, которому присваивается результат вызова метода, ссылаются на один и тот же массив. Но поскольку в теле метода создается локальный экземпляр, то по завершении работы метода Перечисления и структуры 163 он будет из памяти удален. А массив останется, поскольку на массив есть ссылка в программе. Команду с вызовом метода create() можно интерпретировать как экземпляр делегата со всеми вытекающими отсюда последствиями. Например, мы можем вызвать метод show() из подобного выражения, как это сделано в команде Операторные методы в структурах Я за разделение труда, доктор. В Большом пусть поют, я буду оперировать. из к/ф Собачье сердце» Как отмечалось ранее, в структурах можно использовать операторные методы НАЗ А МЕТКУ Напомним, что операторные методы описываются как открытые статические. Название операторного метода получается объединением ключевого слова operator и символа оператора. Количество аргументов операторного метода совпадает с количеством операндов в соответствующей операции (каждый аргумент отождествляется с операндом. Операторный метод должен возвращать результат. В листинге 3.9 представлен очень скромный пример, в котором есть структура с операторными методами. Листинг 3.9. Операторные методы в структурах System; // ɋɬɪɭɤɬɭɪɚ: struct MyNum{ // Ɂɚɤɪɵɬɨɟ ɰɟɥɨɱɢɫɥɟɧɧɨɟ ɩɨɥɟ: private int number; // Ʉɨɧɫɬɪɭɤɬɨɪ: Глава 3 164 public MyNum(int n){ // Ɂɧɚɱɟɧɢɟ ɩɨɥɹ: number=n; } // Ɇɟɬɨɞ ɞɥɹ ɜɵɱɢɫɥɟɧɢɹ ɫɭɦɦɵ ɷɤɡɟɦɩɥɹɪɚ ɫɬɪɭɤɬɭɪɵ // ɢ ɱɢɫɥɚ: public static int operator+(MyNum A,int n){ return !A+n; } // Ɇɟɬɨɞ ɞɥɹ ɜɵɱɢɫɥɟɧɢɹ ɫɭɦɦɵ ɱɢɫɥɚ ɢ // ɷɤɡɟɦɩɥɹɪɚ ɫɬɪɭɤɬɭɪɵ: public static int operator+(int n,MyNum A){ return A+n; } // Ɇɟɬɨɞ ɞɥɹ ɜɵɱɢɫɥɟɧɢɹ ɫɭɦɦɵ ɞɜɭɯ ɷɤɡɟɦɩɥɹɪɨɜ // ɫɬɪɭɤɬɭɪɵ: public static int operator+(MyNum A,MyNum B){ return !A+!B; } // Ɇɟɬɨɞ ɞɥɹ ɭɧɚɪɧɨɝɨ ɨɩɟɪɚɬɨɪɚ: public static int operator!(MyNum A){ return A.number; } } // Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ: class StructAndOperatorDemo{ // Ƚɥɚɜɧɵɣ ɦɟɬɨɞ: static void Main(){ // ɋɨɡɞɚɧɢɟ ɷɤɡɟɦɩɥɹɪɨɜ ɫɬɪɭɤɬɭɪɵ: MyNum A=new MyNum(100); MyNum B=new MyNum(200); // ɂɫɩɨɥɶɡɨɜɚɧɢɟ ɨɩɟɪɚɬɨɪɧɵɯ ɦɟɬɨɞɨɜ ɞɥɹ ɜɵɱɢɫɥɟɧɢɹ Перечисления и структуры // ɡɧɚɱɟɧɢɹ ɜɵɪɚɠɟɧɢɣ: Console.WriteLine( ƎA: {0}Ǝ,!A); Console.WriteLine( ƎB: {0}Ǝ,!B); Console.WriteLine( ƎA+B: {0}Ǝ,A+B); Console.WriteLine( ƎA+10: {0}Ǝ,A+10); Console.WriteLine( Ǝ20+B: {0}Ǝ,20+B); После выполнения программы получаем следующий результат: Результат выполнения программы (из листинга 3.9) A: 100 B: 200 A+B: 300 A+10: 110 20+B: Структура MyNum содержит закрытое целочисленное поле number, конструктор с одним аргументом (определяет значение поля) и несколько версий операторных методов. Точнее, в структуре описаны операторный метод для унарного оператора ! и три версии операторного метода для бинарного оператора сложения +. Действие унарного оператора ! на экземпляр структуры определено таким образом, что результатом возвращается значение целочисленного поля этого экземпляра. Операторный метод для оператора +, когда операндами являются два экземпляра структуры, результатом возвращает сумму целочисленных полей этих экземпляров. Причем в теле операторного метода для получения значения целочисленного поля экземпляра структуры мы использовали оператор !. Далее, сумма экземпляра структуры и числа в результате дает сумму целочисленного поля экземпляра и данного числа. Сумма числа и экземпляра структуры вычисляется как сумма экземпляра структуры и числа. В главном методе программы мы создаем два экземпляра структуры MyNum и сих помощью проверяем работу операторных методов Глава Структуры и события Дикари, аж плакать хочется. из к/ф «Кин-дза-дза» В структурах можно объявлять и использовать события. Логика действий в этом случае такая же, как и при использовании событий в классах. Небольшой пример, дающий общее представление об использовании событий в структурах, представлен в листинге Листинг 3.10. Структуры и события System; // Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ: delegate void MyDelegate(string t); // ɉɟɪɜɚɹ ɫɬɪɭɤɬɭɪɚ: struct Alpha{ // Ɉɬɤɪɵɬɨɟ ɬɟɤɫɬɨɜɨɟ ɩɨɥɟ: public string name; // Ɂɚɤɪɵɬɨɟ ɩɨɥɟ, ɹɜɥɹɸɳɟɟɫɹ ɫɫɵɥɤɨɣ // ɧɚ ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ: private MyDelegate myevent; // Ɉɛɴɹɜɥɟɧɢɟ ɫɨɛɵɬɢɹ: public event MyDelegate MyEvent{ // Ⱥɤɫɟɫɫɨɪ ɞɥɹ ɞɨɛɚɜɥɟɧɢɹ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ // ɜ ɫɩɢɫɨɤ ɨɛɪɚɛɨɬɱɢɤɨɜ ɫɨɛɵɬɢɹ: add{ myevent+=value; } // Ⱥɤɫɟɫɫɨɪ ɞɥɹ ɭɞɚɥɟɧɢɹ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ // ɢɡ ɫɩɢɫɤɚ ɨɛɪɚɛɨɬɱɢɤɨɜ ɫɨɛɵɬɢɹ: remove{ myevent-=value; } Перечисления и структуры } // Ʉɨɧɫɬɪɭɤɬɨɪ: public Alpha(string t){ // Ɂɧɚɱɟɧɢɹ ɩɨɥɟɣ: name=t; myevent=null; } // Ɇɟɬɨɞ ɞɥɹ ɝɟɧɟɪɢɪɨɜɚɧɢɹ ɫɨɛɵɬɢɣ: public void RaiseMyEvent(){ // ȿɫɥɢ ɫɫɵɥɤɚ ɧɟ ɩɭɫɬɚɹ, ɬɨ ɜɵɡɵɜɚɟɬɫɹ // ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ: if(myevent!=null) myevent( ƎAlpha: Ǝ+name); } } // ȼɬɨɪɚɹ ɫɬɪɭɤɬɭɪɚ: struct Bravo{ // Ɉɬɤɪɵɬɨɟ ɬɟɤɫɬɨɜɨɟ ɩɨɥɟ: public string name; // Ɉɛɴɹɜɥɟɧɢɟ ɫɨɛɵɬɢɹ: public event MyDelegate MyEvent; // Ɇɟɬɨɞ ɞɥɹ ɝɟɧɟɪɢɪɨɜɚɧɢɹ ɫɨɛɵɬɢɹ: public void RaiseMyEvent(){ // ȿɫɥɢ ɫɩɢɫɨɤ ɨɛɪɚɛɨɬɱɢɤɨɜ ɧɟ ɩɭɫɬɨɣ, ɬɨ // ɝɟɧɟɪɢɪɭɟɬɫɹ ɫɨɛɵɬɢɟ: if(MyEvent!=null) MyEvent( ƎBravo: Ǝ+name); } } // Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ: class StructAndEventDemo{ // ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ: static void show(string t){ Console.WriteLine( Ǝɉɪɨɢɡɨɲɥɨ ɫɨɛɵɬɢɟƎ); Глава 3 168 Console.WriteLine(t); Console.WriteLine( Ǝ------------------Ǝ); } // Ƚɥɚɜɧɵɣ ɦɟɬɨɞ: static void Main(){ // ɋɨɡɞɚɧɢɟ ɷɤɡɟɦɩɥɹɪɚ ɩɟɪɜɨɣ ɫɬɪɭɤɬɭɪɵ: Alpha A=new Alpha( Ǝɗɤɡɟɦɩɥɹɪ AƎ); // Ⱦɨɛɚɜɥɟɧɢɟ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ ɜ ɫɩɢɫɨɤ ɨɛɪɚɛɨɬɱɢɤɨɜ // ɫɨɛɵɬɢɹ: A. MyEvent+=show; // Ƚɟɧɟɪɢɪɨɜɚɧɢɟ ɫɨɛɵɬɢɹ: A. RaiseMyEvent(); // ɋɨɡɞɚɧɢɟ ɷɤɡɟɦɩɥɹɪɚ ɜɬɨɪɨɣ ɫɬɪɭɤɬɭɪɵ: Bravo B=new Bravo(); // ɉɪɢɫɜɚɢɜɚɧɢɟ ɡɧɚɱɟɧɢɹ ɬɟɤɫɬɨɜɨɦɭ ɩɨɥɸ: B.name= Ǝɗɤɡɟɦɩɥɹɪ BƎ; // Ⱦɨɛɚɜɥɟɧɢɟ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ ɜ ɫɩɢɫɨɤ ɨɛɪɚɛɨɬɱɢɤɨɜ // ɫɨɛɵɬɢɹ: B. MyEvent+=show; // Ƚɟɧɟɪɢɪɨɜɚɧɢɟ ɫɨɛɵɬɢɟ: B. RaiseMyEvent(); Ниже показано, как выглядит результат выполнения программы: Результат выполнения программы (из листинга 3.10) ɉɪɨɢɡɨɲɥɨ ɫɨɛɵɬɢɟ Alpha: ɗɤɡɟɦɩɥɹɪ A ------------------ ɉɪɨɢɡɨɲɥɨ ɫɨɛɵɬɢɟ Bravo: ɗɤɡɟɦɩɥɹɪ B ------------------ Перечисления и структуры 169 В программе есть объявление делегата MyDelegate, соответствующего методам с текстовым аргументом, которые не возвращают результат. Экземпляры этого делегата мы планируем использовать для обработки событий. Также мы описали две структуры Alpha и Bravo. Структуры функционально схожи, но немного по-разному организованы. В структуре Alpha есть открытое текстовое поле name. Закрытое поле myevent типа MyDelegate является ссылкой на экземпляр делегата. Мы это поле используем при описании аксессоров события MyEvent : при добавлении ссылки на метод в список обработчиков события или удалении ссылки из списка в действительности изменения происходят с полем myevent. В структуре также есть конструктор с текстовым аргументом. Текстовый аргумент определяет значение текстового поля name, а поле myevent в качестве значения получает пустую ссылку. В данном случае это момент нетривиальный, поскольку в конструкторе должны быть присвоены значения всем полям экземпляра структуры. Для генерирования события в структуре описан метод RaiseMyEvent(), в теле которого проверяется условие myevent!=null (истинно, если поле myevent содержит ссылки на методы, и при истинном условии командой myevent( ƎAlpha: Ǝ+name) вызывается экземпляр делегата, на который ссылается поле Вторая структура называется Bravo. В ней также есть текстовое поле name . Событие MyEvent объявлено без явного описания аксессоров. Конструктора у структуры нет. Метод RaiseMyEvent() генерирует событие MyEvent при условии, что для события зарегистрированы обработчики ПОДРОБНОСТИ bТо, что в структуре Bravo не описан конструктор — неслучайно. Каждая версия конструктора, которая описывается в структуре, должна присваивать значения полям экземпляра структуры. За событием спрятано поле, которое содержит ссылки на экземпляры делегата, которые вызываются для обработки события. В структуре Alpha такое поле было описано явно, и мы ему присваивали значение в конструкторе. В структуре Bravo мы для события не описываем аксессоры и не объявляем поле для записи ссылок на экземпляры делегата. Такое поле создается автоматически, и присвоить ему значение в конструкторе было бы проблематично. Поэтому от конструктора мы отказались Глава Для обработки событий мы описали статический метод show() стек- стовым аргументом. Метод при вызове отображает значение своего текстового аргумента вместе с поясняющим текстом. В главном методе командой Alpha A=new Alpha( Ǝɗɤɡɟɦɩɥɹɪ AƎ) мы создаем экземпляр первой структуры. Командой A.MyEvent+=show добавляем ссылку на метод show() в список обработчиков события MyEvent экземпляра A. Командой A.RaiseMyEvent() событие генерируется. Аналогичные операции выполняются с экземпляром B структуры Bravo . Заслуживает внимания лишь команда Bravo B=new Bravo(), которой создается экземпляр структуры. Конструктор в структуре Bravo мы не описывали, поэтому теоретически вариантов было два просто объявить экземпляр структуры или использовать инструкцию. Подходит только второй вариант, поскольку в этом случае вызывается конструктор по умолчанию (без аргументов, который инициализирует значениями по умолчанию поля структуры (в том числе и техническое поле, связанное с событием. При объявлении экземпляра структуры без инструкции этого не происходит. Структуры и интерфейсы Я не злоупотребляю. Я, дорогой профессор, только в виде опыта. из к/ф Собачье сердце» Структуры не поддерживают наследование, нов структурах могут быть реализованы интерфейсы. Общая идея такая же, как и при реализации интерфейсов в классах методы, свойства, индексаторы и события, объявленные в интерфейсе, должны быть описаны в структуре, реализующей интерфейс. Если структура реализует интерфейс, тов описании структуры после ее имени (через двоеточие) указывается имя реализуемого интерфейса. Если в структуре реализуется несколько интерфейсов, то имена интерфейсов разделяются запятыми. Программа, в которой иллюстрируется механизм реализации интерфейсов в структурах, представлена в листинге Листинг 3.11. Структуры и интерфейсы System; // ɂɧɬɟɪɮɟɣɫ: Перечисления и структуры MyInterface{ // Ɇɟɬɨɞɵ: void set(int n); void show(); } // ɋɬɪɭɤɬɭɪɚ ɧɚɫɥɟɞɭɟɬ ɢɧɬɟɪɮɟɣɫ: struct MyStruct:MyInterface{ // Ɂɚɤɪɵɬɨɟ ɰɟɥɨɱɢɫɥɟɧɧɨɟ ɩɨɥɟ: private int code; // Ɇɟɬɨɞ ɢɡ ɢɧɬɟɪɮɟɣɫɚ: public void set(int n){ code=n; } // Ɇɟɬɨɞ ɢɡ ɢɧɬɟɪɮɟɣɫɚ: public void show(){ Console.WriteLine( Ǝɑɢɫɥɨɜɨɟ ɩɨɥɟ Ǝ+code); } } // Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ: class StructAndInterfaceDemo{ // Ƚɥɚɜɧɵɣ ɦɟɬɨɞ: static void Main(){ // ɋɨɡɞɚɧɢɟ ɷɤɡɟɦɩɥɹɪɚ ɫɬɪɭɤɬɭɪɵ: MyStruct A=new MyStruct(); // ȼɵɡɨɜ ɦɟɬɨɞɚ ɞɥɹ ɩɪɢɫɜɚɢɜɚɧɢɹ ɡɧɚɱɟɧɢɹ ɩɨɥɸ: A.set(100); Console.WriteLine( Ǝɗɤɡɟɦɩɥɹɪ A:Ǝ); // ȼɵɡɨɜ ɦɟɬɨɞɚ ɞɥɹ ɨɬɨɛɪɚɠɟɧɢɹ ɡɧɚɱɟɧɢɹ ɩɨɥɹ: A.show(); // ɂɧɬɟɪɮɟɣɫɧɚɹ ɩɟɪɟɦɟɧɧɚɹ: MyInterface R; // ɂɧɬɟɪɮɟɣɫɧɨɣ ɩɟɪɟɦɟɧɧɨɣ ɡɧɚɱɟɧɢɟɦ ɩɪɢɫɜɚɢɜɚɟɬɫɹ Глава 3 172 // ɷɤɡɟɦɩɥɹɪ ɫɬɪɭɤɬɭɪɵ: R=A; Console.WriteLine( Ǝɉɟɪɟɦɟɧɧɚɹ R:Ǝ); // ȼɵɡɨɜ ɦɟɬɨɞɚ ɞɥɹ ɨɬɨɛɪɚɠɟɧɢɹ ɡɧɚɱɟɧɢɹ ɩɨɥɹ: R.show(); // ȼɵɡɨɜ ɦɟɬɨɞɚ ɞɥɹ ɩɪɢɫɜɚɢɜɚɧɢɹ ɡɧɚɱɟɧɢɹ ɩɨɥɸ: R.set(200); Console.WriteLine( Ǝɉɟɪɟɦɟɧɧɚɹ R:Ǝ); // ȼɵɡɨɜ ɦɟɬɨɞɚ ɞɥɹ ɨɬɨɛɪɚɠɟɧɢɹ ɡɧɚɱɟɧɢɹ ɩɨɥɹ: R.show(); Console.WriteLine( Ǝɗɤɡɟɦɩɥɹɪ A:Ǝ); // ȼɵɡɨɜ ɦɟɬɨɞɚ ɞɥɹ ɨɬɨɛɪɚɠɟɧɢɹ ɡɧɚɱɟɧɢɹ ɩɨɥɹ: A.show(); Результат выполнения программы следующий: Результат выполнения программы (из листинга 3.11) ɗɤɡɟɦɩɥɹɪ A: ɑɢɫɥɨɜɨɟ ɩɨɥɟ 100 ɉɟɪɟɦɟɧɧɚɹ R: ɑɢɫɥɨɜɨɟ ɩɨɥɟ 100 ɉɟɪɟɦɟɧɧɚɹ R: ɑɢɫɥɨɜɨɟ ɩɨɥɟ 200 ɗɤɡɟɦɩɥɹɪ A: ɑɢɫɥɨɜɨɟ ɩɨɥɟ Интерфейс называется MyInterface, ив нем объявлены два метода метод set() с целочисленным аргументом и метод show() без аргументов (результат методы не возвращают. Структура MyStruct реализует интерфейс MyInterface. В структуре объявлено закрытое целочисленное поле code. Метод set() предназначен для присваивания Перечисления и структуры 173 значения полю code, а метод show() нужен для отображения значения поля. В методе Main() командой MyStruct A=new MyStruct() создается экземпляр структуры. Создавать экземпляр нужно именно такс использованием инструкции new), поскольку поле code закрытое, а перед вызовом любого метода поля должны быть инициализированы. Использованный нами способ создания экземпляра подразумевает вызов конструктора по умолчанию, вследствие чего поле code инициализируется с начальным нулевым значением. Значение 100 полю code экземпляра A присваиваем с помощью команды. Для проверки значения поля экземпляра A используем команду Командой MyInterface R объявляется интерфейсная переменная. Поскольку структура MyStruct реализует интерфейс MyInterface, то интерфейсной переменной можно присвоить в качестве значения экземпляр структуры (команда R=A). Через интерфейсную переменную доступ будет только к тем методам, которые объявлены в интерфейсе. Ноне это главное. Дело в том, что структура относится к типу данных с прямым доступом к значению. Поэтому при выполнении команды R=A переменная R в качестве значения получает ссылку на копию экземпляра ПОДРОБНОСТИ bПри выполнении команды R=A создается копия экземпляра и ссылка на эту копию записывается в переменную R . Значением переменной R является ссылка, а не экземпляр. Интерфейсная переменная ссылается на копию экземпляра A структуры MyStruct также, как объектные переменные ссылаются на объекты классов. Если объявить еще одну интерфейсную переменную P интерфейса MyInterface , а затем выполнить команду P=R , то переменные P и будут ссылаться на один и тот же экземпляр и этот экземпляр будет копией экземпляра Значение поля code экземпляра, на который ссылается интерфейсная переменная R, проверяем с помощью команды R.show(). После выполнения команды R.set(200) меняется значение поля code экземпляра, на который ссылается интерфейсная переменная R. Значение поля code Глава экземпляра A остается неизменным. Убеждаемся в этом с помощью команд) и A.show(). Резюме Даль моей карьеры видна мне совершенно от- четливо. из к/ф Собачье сердце Перечисление представляет собой тип данных, формируемый набором целочисленных констант. При объявлении перечисления указывается ключевое слово enum , название перечисления, а в фигурных скобках перечисляются названия констант. По умолчанию константы получают значения, начиная с нуля. Значение каждой следующей константы на единицу больше предыдущей константы в списке. При необходимости значения для констант можно указать в явном виде Переменной, типом которой указано перечисление, можно присваивать в качестве значения одну из констант в перечислении. Константа указывается вместе с именем перечисления. Имя перечисления и название константы разделяются точкой. В случае необходимости можно применять явное преобразование типов Структура напоминает классно в отличие от класса, относящегося к ссылочным типам, структура относится к типу с прямым доступом к значению. Описывается структура подобно классу, но вместо ключевого слова class используется ключевое слово struct • По сравнению с классами, на структуры накладываются определенные ограничения. Членами структуры могут быть поля, методы, свойства, индексаторы и события. Члены структуры могут быть открытыми и закрытыми (по умолчанию. Ключевое слово protected не используется Методы в структуре могут перегружаться, а также могут использоваться операторные методы В структуре могут описываться конструкторы. Конструктор без аргументов используется по умолчанию, и его нельзя переопределить У структуры нет деструктора. Перечисления и структуры Структуры не поддерживают наследование, но могут реализовать интерфейсы Экземпляр структуры может создаваться простым объявлением переменной, типом которой указана структура. В этом случае поля структуры не инициализируются, и перед первым использованием экземпляра структуры полям необходимо присвоить значение Экземпляр структуры можно создавать таким же образом, как и объект класса, с использованием инструкции new . В этом случае при создании экземпляра вызывается конструктор, версия которого определяется переданными конструктору аргументами. Если аргументы конструктору не переданы, то вызывается конструктор по умолчанию, в результате чего поля экземпляров структуры инициализиру- ются значениями по умолчанию Значением переменной типа структуры является экземпляр структуры. Если одному экземпляру структуры присваивается в качестве значения другой экземпляр структуры, то выполняется побитовое копирование полей. |