Вложенные классы. Вложенные статические классы. Объявление и использование вложенных классов. Примеры
Содержание
- 1. Понятие вложенного класса. Общая форма объявления вложенного класса
- 2. Как выглядит общая форма объявления объекта вложенного класса?
- 3. Какие модификаторы доступа могут применяться к вложенным классам?
- 4. Пример, который демонстрирует использование классов с различными модификаторами доступа
- 5. Объявление и использование статического вложенного класса в нестатическом. Пример
- 6. Можно ли в статическом классе объявить нестатический вложенный класс?
- 7. Пример объявления и использования статического вложенного класса в другом статическом классе
- Связанные темы
Поиск на других ресурсах:
1. Понятие вложенного класса. Общая форма объявления вложенного класса
В языке C# любой класс в своей реализации может содержать объявление другого класса. Класс, который объявляется в пределах фигурных скобок другого класса, называется вложенным классом.
В простейшем случае, общая форма объявления вложенного класса в классе имеет вид:
// класс, который содержит в реализации объявление другого класса class Outer { // поля и методы класса Outer // ... class Inner { // поля и методы класса Inner // ... } // поля и методы класса Outer // ... }
где
- Outer – имя класса, который содержит в своем теле объявление другого класса с именем Inner;
- Inner – имя класса, который объявляется в классе Outer.
Классы Outer и Inner могут содержать различные спецификаторы, которые определяют доступ (private, protected, public) или другие свойства класса (static, sealed и т.д.).
⇑
2. Как выглядит общая форма объявления объекта вложенного класса?
Объект вложенного класса можно объявить в случае, когда вложенный класс объявлен как видимый. Это значит, что видимый вложенный класс должен быть объявлен с любым модификатором доступа кроме private.
Если вложенный класс объявлен как не private-класс, то создание экземпляра этого класса имеет следующий вид:
Outer.Inner objInner = new Outer.Inner();
где
- Outer – имя внешнего класса, в котором объявляется вложенный класс Inner;
- Inner – имя вложенного класса, который объявлен в пределах фигурных скобок класса Outer;
- objInner – имя объекта (экземпляра) класса, который создается;
- Outer.Inner() – имя конструктора по умолчанию, который вызывается для создания объекта класса. Если в классе Inner реализованы другие параметризированные конструкторы, то этот вызов может быть другим.
⇑
3. Какие модификаторы доступа могут применяться к вложенным классам?
К вложенным классам могут применяться точно такие же модификаторы доступа как и к обычным – невложенным классам:
- private. В этом случае вложенный класс есть видимым в пределах фигурных скобок { } внешнего класса;
- public. В этом случае вложенный класс доступен в пределах внешнего класса, из экземпляра внешнего класса, из унаследованного класса а также за пределами сборки;
- protected. В этом случае класс есть доступен в пределах внешнего класса а также из методов унаследованных классов;
- internal. Вложенный класс есть доступен в пределах сборки и недоступен за пределами сборки;
- protected internal. Вложенный класс может быть доступен из методов внешнего класса, методов унаследованных классов или недоступен из методов за пределами текущей сборки.
Действие модификаторов точно такое же как и в случае с членами данных (методами) класса.
⇑
4. Пример, который демонстрирует использование классов с различными модификаторами доступа
В примере демонстрируется объявление и доступ к вложенным классам, которые содержат различные модификаторы доступа.
Объявляется класс Outer, который содержит:
- две внутренние public-переменные с именами d и sd. Переменная sd объявлена как статическая;
- внутренний метод GetInner1(), демонстрирующий доступ к private-классу Inner1;
- вложенный класс Inner1, который объявлен как private;
- вложенный класс Inner2, который объявлен как public;
- вложенный класс Inner3, который объявлен как internal;
- вложенный класс Inner4, который объявлен как protected;
- вложенный класс Inner5, который объявлен как protected internal.
В любом из вложенных классов объявляются:
- одна нестатическая переменная целого типа;
- одна статическая переменная целого типа.
Листинг класса Outer следующий:
// класс Outer содержит 5 вложенных классов public class Outer { // внутренние переменные класса Outer public int d; static public int sd; // доступ к private-классу Inner1 из внутреннего метода класса public Inner1 GetInner1() { Inner1 i1 = new Inner1(); // создать экземпляр класса Inner1 // доступ к члену данных класса Inner1 через экземпляр класса i1.d1 = 25; // доступ к статическому члену вложенного класса Inner1 Inner1.sd1 = 30; return i1; } // private-вложенный класс Inner1 private class Inner1 { public int d1; public static int sd1; } // public-вложенный класс Inner2 public class Inner2 { public int d2; public static int sd2; } // internal-вложенный класс Inner3 internal class Inner3 { public int d3; public static int sd3; } // protected-вложенный класс Inner4 protected class Inner4 { public int d4; public static int sd4; } // protected-internal вложенный класс Inner5 protected internal class Inner5 { public int d5; public static int sd5; } }
Использование вложенных классов в некотором методе может быть следующим:
// Использование вложенных классов Outer.Inner1, Outer.Inner2, Outer // 1. Объявить объект класса Outer Outer o = new Outer(); o.d = 300; // доступ к внутренней переменной через экземпляр класса Outer Outer.sd = 230; // доступ к статической переменной // 2. Нет доступа к private-классу Inner1 через экземпляр класса Outer // Outer.Inner1 i1; - ошибка, класс Inner1 объявлен как private // 3. Объявить объект public-класса Inner2 Outer.Inner2 i2 = new Outer.Inner2(); i2.d2 = 440; Outer.Inner2.sd2 = 500; // доступ к статической переменной // 4. Объявить объект internal-класса Inner3 Outer.Inner3 i3 = new Outer.Inner3(); i3.d3 = 100; Outer.Inner3.sd3 = 400; // доступ к статической переменной // 5. Объявить объект protected-класса можно только из унаследованных классов // Outer.Inner4 i4; - ошибка // 6. Объявить объект protected-internal-класса можно Outer.Inner5 i5 = new Outer.Inner5(); i5.d5 = 200; Outer.Inner5.sd5 = -100;
Как видно из вышеприведенного кода, создавать объекты можно только для классов Inner2, Inner3, Inner5. Чтобы создать объект protected-класса Inner4, нужно объявить другой класс, который наследует класс Outer, например:
// класс Outer2 есть унаследованным от класса Outer class Outer2 : Outer { // в методе унаследованного класса есть доступ к protected-классу Inner4 void SomeMethod() { // создать экземпляр класса Outer.Inner4 Inner4 i4 = new Inner4(); // работает i4.d4 = 23; // доступ через экземпляр класса Inner4.sd4 = 330; // доступ к статической переменной } }
Данный пример также показывает, что вложенный private-класс скрывает доступ к объявленной в нем статической переменной из методов других классов. Так же, скрывает доступ и вложенный protected-класс.
⇑
5. Объявление и использование статического вложенного класса в нестатическом. Пример
В нестатическом классе может быть объявлен статический класс (с ключевым словом static). Это означает, что статический класс данного класса есть уникальным общим ресурсом. Доступ к элементам статического класса осуществляется непосредственно по имени статического класса, перед которым через точку следует имя (имена) внешнего класса (классов).
Пример. Объявляется класс Outer, содержащий объявление вложенного статического (static) класса Inner. В классе Inner объявляется статическая внутренняя public-переменная. Текст класса Outer следующий:
// класс Outer - нестатический public class Outer { // внутренние переменные класса Outer public int d; static public int sd; // статический вложенный класс Inner public static class Inner { // только статические переменные могут объявляться в статическом классе public static int sd; // статическая внутренняя переменная класса Inner } }
Использование статического вложенного класса может быть приблизительно таким:
// доступ к статической переменной статического класса Outer.Inner Outer.Inner.sd = 45; // создать объект (экземпляр) класса Outer Outer o = new Outer(); o.d = 30; // есть доступ к переменным экземпляра класса через объект Outer.sd = 102; // доступ к статической переменной класса Outer // создавать объект статического класса нельзя //Outer.Inner i = new Outer.Inner(); - это ошибка!
⇑
6. Можно ли в статическом классе объявить нестатический вложенный класс?
Да, можно. В статическом классе можно объявлять нестатические вложенные классы. Однако, в статическом классе нельзя объявлять нестатические переменные и методы.
Более подробно об использовании статических переменных, методов, классов описывается в теме:
Например. Пусть объявляется статический класс Outer, содержащий реализацию нестатического класса Inner
// класс Outer - статический public static class Outer { // внутренние переменные класса Outer // только статические экземпляры можно объявлять в статическом классе // public int d; - ошибка! static public int sd; // нестатический вложенный класс Inner - может объявляться в статическом классе public class Inner { public int d; // нестатическая переменная public static int sd; // статическая внутренняя переменная класса Inner } }
Использование классов Outer и Outer.Inner может быть, например, таким:
// использование нестатического класса в статическом классе // доступ к статической переменной sd класса Outer.Inner Outer.Inner.sd = 230; // доступ к статической переменной sd класса Outer Outer.sd = 132; // Нельзя создавать экземпляр (объект) статического класса // Outer o = new Outer(); // ошибка, поскольку Outer - статический класс // создать экземпляр вложенного класса Outer.Inner Outer.Inner i = new Outer.Inner(); і.d = 323; // доступ к нестатической переменной d класса Outer.Inner
⇑
7. Пример объявления и использования статического вложенного класса в другом статическом классе
В статическом классе может быть объявлен другой вложенный статический класс. Здесь следует помнить, что в статических классах объявленные методы и переменные должны обязательно быть статическими (за исключением классов). А вот классы могут быть и нестатическими.
Пусть заданы объявления статических классов Outer и Inner:
// класс Outer - статический public static class Outer { // только статические экземпляры можно объявлять в статическом классе static public int sd; // статический вложенный класс Inner - может объявляться в статическом классе public static class Inner { // здесь только статические элементы public static int sd; // статическая внутренняя переменная класса Inner } }
Тогда, использование статических элементов этих классов может быть следующим:
// использование статического класса в статическом классе // доступ к статической переменной sd класса Outer.Inner Outer.Inner.sd = 140; // доступ к статической переменной sd класса Outer Outer.sd = 110; // Нельзя создавать экземпляр (объект) статического класса // Outer o = new Outer(); // ошибка, поскольку Outer - статический класс
⇑
Связанные темы
- Понятие класса. Общая форма объявления класса. Объект класса. Поля класса. Примеры.Ключевое слово this. Вложенные классы
- Статические классы, методы, переменные. Статические конструкторы. Ключевое слово static