Вложенные классы (Inner)

Можно создавать классы внутри других классов – вложенные классы. Они могут работать со всеми членами внешнего класса.

Пример 1. В класс Outer помещено два класса Inner1, Inner2

public class Outer {

int y;

Outer (int x) {// конструктор

y=x;

}

class Inner1 {… public int f1() {return y++;} } //внутренний класс

int g (String s) { // метод

class Inner 2 {…}// локальный внутренний класс

}

}

Компилятор сделает файлы: Outer.class

Outer$Inner1.class

Outer$Inner2.class

Порождение объекта внутри класса Outer: Inner1 i1 = new Inner1 ();

Порождение снаружи: Outer t1 = new Outer ();

Outer.Inner1 i2 = t1. new Inner1(); // t1 -объект класса Outer

Пример 2.

public class Parcel1{

void f() {}

_________________________________________________________________________

class Contents {

private int i =11;

public int value () {return i;}

public Parsel1 outer(){ return Parsel1.this; }//синтаксис!!!

} //ссылка на внешний класс

___________________________________________________________________________

class Destination {//пакетный доступ,может быть и private-тогда снаружи

//нельзя создать объект

private String label;

Destination (String whereTo) {// конструктор

label = where To;

}

String readLabel () {return label;}

}

______________________________________________________________________________

public void ship (String dest) {

Contents c = new Contents ();//создаем объекты внутренних

//внутри внешних

Destination d = new Destination (dest);

System.out.println (d.readLabel()); //используется метод

//внутреннего класса.

}

public Contents cont () {return new Contents ();}//создаем объект

//внутреннего класса

public static void main (String [] args) {

Parcel1 p = new Parcel1 ();

p.ship (“Тасмания”);

Parcel1 q = new Parcel1();

Parcel1.Contents c = q.cont();//имя внутреннего класса

Parcel1.Destination d = p.new Destination (“Танзания”);

c.outer().f();

}

}// Тасмания

Внутренний класс содержит скрытую ссылку на внешний. Объект внутреннего класса можно создать только в сочетании с объектом внешнего.

Внутренний класс получает доступ к членам внешнего класса.

interface Selector { //для перебора элементов массива (итератор)

boolean end(); // достигнут ли конец последовательности?

Object current(); // обратиться к текущему объекту

void next(); // перейти к следующему объекту

}

public class Sequence { //оболочка для массива Object с размером size

private Object[] items;

private int next = 0;

public Sequence(int size){ items = new Object[size]; }//конструктор

public void add(Оbject x) { // добавление новых объектов к массиву

if (next < items.lenght)

items[next++] = x;

}

private class SequenceSelector implements Selector { //закрытый

//класс, реализующий Selector

private int i = 0; // поле внутреннего класса

public boolean end() {return i == items. length;}//работаем с

//закрытым полем внешнего класса

public void next() { if(i < items. length) i++; }

}

public Selector getSelector() {//вернем Selector!!!!!

return new SequenceSelector();

}

public static void main(String[] args) {

Sequence sequence = new Sequence(10);

for (int i=0; i<10; i++)

Sequence.add(Integer.toString(i)); // создание

//последовательности с заполнением String

Selector selector = sequence.getSelector(); // получили ссылку на

// Selector

while (!selector.end()){//передвигаемся по последовательности

System.out.print(selector.current() + “ ”);

selector.next();

}// while

}// main

}//class

//0 1 2 3 4 5 6 7 8 9

Внутренний класс может обращаться ко всем полям и методам внешнего.

Зачем нужны внутренние классы ???

Обычно внутренний класс реализует интерфейс или наследует от какого – либо класса. А его код имеет доступ к членам внешнего класса.

Почему не реализовать интерфейс внешним классом?

1) Проектирование. Внутренний класс не обязан реализовывать отношение is – a. (Sequence не является Selector). Кроме того, можно создать еще один внутренний класс Selector, для перебора, например, в обратном направлении (метод reverceSelector () его вернет).

Это дает гибкость-несколько внутренних классов, реализующих один интерфейс.

2) Можно наследовать от нескольких классов: внешний класс от одного, внутренний – от другого (множественное наследование реализации). То есть наследование от многих не интерфейсов, а классов.

3) Можно создать несколько экземпляров внутреннего класса (Selector), которые будут работать одновременно.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: