Внутренние и вложенные классы java
02.03.2017 — 2019 год
Часть 2
Внутренние классы
Inner Classes — Внутренние классы
Внутренний класс связан с экземпляром его обрамляющего класса (из документации).
Пример внутреннего класса есть в документации.
Создадим класс:
/* Пример №7 */
//
class OuterClass {
...
class InnerClass {
...
}
}
Так в чем же отличие, спросите вы. Объявления классов и вложенных и внутренних
одинаковые в данных случаях. Отличие в том, что внутренний класс связан с внешним классом через экземпляр, или через объект класса.
Чтобы создать экземпляр внутреннего класса, нам нужно сначала создать экземпляр внешнего класса. Затем создать внутренний объект, в пределах внешнего объекта, таким образом:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Пример:
* Пример №8 */
package inner;
/**
*
* @author Ar20L80
*/
public class Outer {
class InnerClass {
}
Outer(){
}
public static void main(String[] args) {
Outer outerObject = new Outer();
Outer.InnerClass innerObject = outerObject.new InnerClass(); // создание экземпляра внутреннего класса
}
}
По-другому мы можем написать так:
/*
Пример №9
Внутренние классы
Получить ссылку на внешний класс в конструкторе внутреннего
*/
package inner;
/**
*
* @author Ar20L80
*/
public class Outer5 {
class Inner5{
private Outer5 myOuter;
Inner5(){
myOuter = Outer5.this;
}
}
public static void main(String[] args){
Outer5 outer5 = new Outer5();
}
}
Рассмотрим свойства внутренних классов.
Внутренние классы есть смысл использовать, если они будут использовать элементы родителя,
чтобы не передавать лишнего в конструкторах.
Внутренний класс стоит использовать, когда он никому не нужен, кроме как внешнему классу.
Например, Map.Entry — нигде кроме интерфейса Map и его реализаций он не нужен.
/*
Пример №10 .
Внутренние классы
*/
package inner;
/**
*
* @author Ar20L80
*/
class AnyClass{} // класс от которого наследуем Inner6
public class Outer6 {
class Inner6 extends AnyClass{
// тут мы унаследовали внутренний класс от AnyClass{}
// и можем расширить функциональность класса AnyClass{}
// и класса Outer6
}
}
В этом примере у нас, по сути, получилось множественное наследование, и мы можем использовать функционал класса AnyClass и функционал класса Outer6.
Дополним пример.
/*
пример №11
Внутренние классы
*/
package inner;
/**
*
* @author Ar20L80
*/
class AnyClass2{
void anyClass2Method(){}
}
public class Outer7 {
private int iOuterVar;
private class Inner7 extends AnyClass2
{
private Outer7 out7;
public Inner7() {
out7 = Outer7.this; // ссылка на окружающий класс
}
private int anyMethodOfInner7(){
super.anyClass2Method();// можем вызвать метод нашего супер класса AnyClass2
return out7.iOuterVar; // можем обратиться к переменным
// и методам Outer7
}
}
}
В этом примере видно, что мы можем использовать как поля и методы «окружающего» класса — Outer7, так поля и методы того класса, от которого мы наследовали внутренний класс — AnyClass2.
Это дает нам несколько большие возможности и гибкость при использовании внутреннего класса.
Совет из книги «Философия Java. Брюс Эккель. ISBN 5-272-00250-4» c. 313:
«Каждый внутренний класс может независимо наследовать определенную реализацию.
Внутренний класс не ограничен при наследовании в ситуациях, где внешний класс уже наследует реализацию.»
Чтобы использовать внутренний класс за пределами обычных методов «окружающего» класса необходимо создать объект внутреннего класса следующим способом.
ИмяВнешнегоКласса.ИмяВнутреннегоКласса.
Объект внутреннего класса сохраняет информацию о месте, где он был создан.
Продолжение следует…
Литература
Майкл Морган. «Java 2.Руководство разработчика» ISBN 5-8459-0046-8
Брюс Эккель. «Философия Java.» ISBN 5-272-00250-4
Герберт Шилдт «Java. Полное руководство. 8-е издание.» ISBN: 978-5-8459-1759-1
Ссылки:
ru.wikipedia.org
src-code.net/lokalnye-vnutrennie-klassy-java
Автор: Ar20L80