КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Внутренние (inner) классыНестатические вложенные классы принято называть внутренними (inner) классами. Доступ к элементам внутреннего класса возможен из внешнего класса только через объект внутреннего класса, который должен быть создан в коде внешнего класса. Объект внутреннего класса всегда ассоциируется (скрыто хранит ссылку) с создавшим его объектом внешнего класса – так называемым внешним (enclosing) объектом. Внешний и внутренний классы могут выглядеть, например, так: classOwner{ //поля и методы [доступ]class Inner [extends Cl][implements Interf]{ // поля и методы } } Методы внутреннего класса имеют прямой доступ ко всем полям и методам внешнего класса, в то же время внешний класс может получить доступ к допустимому содержимому внутреннего класса только после создания объекта внутреннего класса. Внутренние классы не могут содержать статические атрибуты и методы, кроме констант (final static). Внутренние классы имеют право наследовать другие классы, реализовывать интерфейсы и выступать в роли объектов наследования. Допустимо наследование следующего вида: class ExtendOwner extends Owner { class ExtendInner extends Inner {} Inner ref = new ExtendInner(); } Если внутренний класс наследуется обычным образом, то он теряет доступ к полям своего внешнего класса, в котором он был объявлен. class New extends Owner.Inner { New(Owner ob){ ob.super(); } } В данном случае конструктор класса New должен быть объявлен с параметром типа Owner, что позволит получить доступ к ссылке на внутренний класс, наследуемый классом New. При объявлении внутреннего класса могут использоваться модификаторы final, abstract, private, protected, public. /* пример # 1 : простой внутренний класс : SimpleDemo.java */ class Owner { class Content { private int count = 220; public int getCount() { return count; } } void show() { Content c = new Content(); System.out.println(c.getCount()); } } public class SimpleDemo { public static void main(String[] args) { Owner ob = new Owner(); ob.show(); //Content content = new Content();//недоступен } } Вложенные классы (nested) Если не существует необходимости в связи объекта внутреннего класса с объектом внешнего класса, то есть смысл сделать такой класс статическим. При объявлении такого внутреннего класса присутствует служебное слово static, и такой класс называется вложенным (nested). Если класс вложен в интерфейс, то он становится статическим по умолчанию. Такой класс способен наследовать другие классы, реализовывать интерфейсы и являться объектом наследования для любого класса, обладающего необходимыми правами доступа. Подкласс вложенного класса не способен унаследовать возможность доступа к членам внешнего класса, которыми наделен его суперкласс. В то же время статический вложенный класс для доступа к нестатическим членам и методам внешнего класса должен создавать его объект, а напрямую доступны только статические поля и методы внешнего класса. Для создания объекта вложенного класса объект внешнего класса создавать нет необходимости. /* пример # 5 : вложенный класс : NestedClassDemo.java */ class Owner3 { static int y = 1, z = 2; public void method1() { //вызов нестатического метода статического класса new Nested().method2(); } //abstract, final, private, public - допустимы protected static class Nested { public static void showN() { System.out.println("z=" + z + " y=" + Owner3.y); } public void method2() { System.out.println("non-static"); } } } public class NestedClassDemo { public static void main(String[] args) { Owner3.Nested.showN(); //статический Owner3 ob = new Owner3(); ob.method1(); } } В результате будет выведено: z=2 y=1
|