
- •Доступность полей/методов классов
- •Абстрактные классы
- •Пример использования абстрактного класса (1)
- •Пример использования абстрактного класса (2)
- •Пример использования абстрактного класса (3)
- •Интерфейсы
- •Объявление интерфейса
- •Заголовок интерфейса
- •Поле интерфейса
- •Метод интерфейса
- •Особенности наследования интерфейсов (1)
- •Особенности наследования интерфейсов (2)
- •Особенности наследования интерфейсов (3)
- •Интерфейсы-маркеры
- •Применение интерфейсов и абстрактных классов (1)
- •Применение интерфейсов и абстрактных классов (2)
- •Применение интерфейсов и абстрактных классов. Пример(1)
- •Применение интерфейсов и абстрактных классов. Пример(2)
- •Применение интерфейсов и абстрактных классов. Пример(3)
- •Внутренние классы
- •Статические внутренние классы-члены (и интерфейсы)
- •Применение статических внутренних классов (1)
- •Применение статических внутренних классов (2)

Статические внутренние классы-члены (и интерфейсы)
Декларируются внутри основного класса наравне с полями и методами с использованием
спецификатора static. Имеют доступ только к статическим полям/методам своего внешнего класса (и, естественно, к собственным членам), даже если они частные (private).
Могут содержать статические поля, методы и классы, в отличие от других типов внутренних классов.
Могут содержать нестатические поля и методы. Нестатические поля/методы возникают только при создании экземпляра этого класса.
Пример статического внутреннего класса:
class OuterClass( ) { |
|
public OuterClass( ) { } |
// конструктор |
private int outerField; |
|
static private int staticOuterField; |
|
static class InnerClass { |
|
int getOuterField( ) { |
|
return OuterClass.this.outerField; // здесь будет ошибка компиляции
}
int getStaticOuterField( ) {
return OuterClass.staticOuterField; // здесь правильно
}
}
//из методов класса OuterClass можно вызывать
//методы внутреннего InnerClass’a
}

Применение статических внутренних классов (1)
Пусть, например, пишется программа, используемая в автоматизированных экзаменах.
public class Question { private Type type; public Type getType() {
return type;
}
public void setType(Type type) { this.type = type;
}
public static enum Type {
SINGLE_CHOICE, MULIT_CHOICE, TEXT
}
}
В вопросе (класс Question) понятие "типа вопроса" (class Type) является очевидным. Другая альтернатива - создать класс верхнего уровня QuestionType - будет менее выразительной, по крайней мере в контексте класса Question.
Клиентский код будет выглядеть, например, так:
Question.Type type = question.getType(); if (type == Question.Type.TEXT) { ... }
Снаружи обращение к классу Type осуществляется через имя обрамляющего класса - Question.Type.

Применение статических внутренних классов (2)
Еще одно интересное использование статических вложенных классов - тестирование приватных статических методов. Пример:
public class ClassToTest { |
|
private static int internalMethod( … ) { |
// тестируемый метод |
... |
|
} |
|
public static class Test { |
|
public void testMethod() { |
|
... |
|
assert TEST_CONST_N == internalMethod( … ) : ERROR_CODE_N;
…
}
}
}
Тестирование заключается в вызовах извне методов класса Test, имеющих вид:
ClassToTest.Test.testMethod();
Тестируемый класс, очевидно, никак не использует свой внутренний статический класс. Результат компиляции программы будет содержать файлы:
ClassToTest.class ClassToTest$Test.class
После завершения тестирования и перед созданием jar-архива для распространения приложения все файлы с именами вида *$Test*.class могут быть удалены при выполнении build-скрипта. На работоспособность оставшихся файлов это никак не повлияет.