Какие виды классов есть в java?
Расскажите про вложенные классы. В каких случаях они применяются?
Класс называется вложенным (Nested class), если он определен внутри другого класса. Вложенный класс должен создаваться только для того, чтобы обслуживать обрамляющий его класс.
Если вложенный класс оказывается полезен в каком-либо ином контексте, он должен стать классом верхнего уровня.
Вложенные классы имеют доступ ко всем (в том числе приватным) полям и методам внешнего класса, но не наоборот.
Что такое «локальный класс»? Каковы его особенности?
Local inner class (Локальный класс) - это вложенный класс, созданный внутри тела метода. Только этот метод имеет к ним доступ.
public class OuterClass {
public void someMethod(){
class LocalClass{
}
}
}Локальные классы имеют следующие особенности:
* Видны только в пределах блока, в котором объявлены;
* Не могут быть объявлены как private/public/protected или static;
* Не могут иметь внутри себя статических объявлений (полей, методов, классов);
* Имеют доступ к полям и методам обрамляющего класса;
* Могут обращаться к локальным переменным и параметрам метода, если они объявлены с модификатором final.
* Может наследовать: обычные классы; внутренние классы в OuterClassе и его предках; такие же локальные классы определённые в том же методе.
* Может быть наследован таким же локальным классом определённом в том же методе.
* Может имплементировать интерфейс
Что такое «анонимные классы»? Где они применяются?
Анонимный класс - Это вложенный локальный класс без имени. Класс, определяемый как подкласс некоторого данного класса прямо в процессе задания переменной.
public class OuterClass {
public void someMethod(){
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
return null;
}
};
}
}Анонимные классы имеют несколько ограничений:
Каким образом из вложенного класса получить доступ к полю внешнего класса?
1) Статический вложенный класс имеет прямой доступ только к статическим полям обрамляющего класса.
2) Простой вложенный класс, может обратиться к любому полю внешнего класса напрямую.
3) В случае, если у вложенного класса уже существует поле с таким же литералом, то обращаться к внешнему полю следует через имя внешнего класса. Например: Outer.this.field.
Что такое перечисления (enum)?
Методы:
* valueOf() возвращает конкретный элемент;
* ordinal() возвращает порядковый номер определенной константы (нумерация
начинается с 0);
* values() возвращает массив всех констант перечисления;
* name() отличается от toString тем, что второй можно переопределить.
Особенности Enum-классов
Недостатки Enum-классов
Что такое Ромбовидное наследование?
Ромбовидное наследование (англ. diamond inheritance) – ситуация в объектно- ориентированных языках программирования с поддержкой множественного наследования, когда два класса B и C наследуют от A, а класс D наследует от обоих классов B и C.
При этой схеме наследования может возникнуть неоднозначность: если объект класса D вызывает метод, определенный в классе A (и этот метод не был переопределен в классе D), а классы B и C по-своему переопределили этот метод, то от какого класса его наследовать:
B или C?
Как проблема ромбовидного наследования решена в java?
В Java нет поддержки множественного наследования классов.
Предположим, что SuperClass – это абстрактный класс, описывающий некоторый метод, а
классы ClassA и ClassB – обычные классы наследники SuperClass, а класс ClassC
наследуется от ClassA и ClassB одновременно. Вызов метода родительского класса
приведет к неопределенности, так как компилятор не знает о том, метод какого именно
суперкласса должен быть вызван. Это и есть основная причина, почему в Java нет
поддержки множественного наследования классов. Интерфейсы – это только
резервирование/описание метода, а реализация самого метода будет в конкретном классе, реализующем эти интерфейсы, таким образом исключается неопределенность при множественном наследовании интерфейсов. В случае, если вызывается default-метод из интерфейса его обязательно надо будет переопределить.
Проблема ромбовидного наследования в Java решается с помощью интерфейсов или с помощью класса абстрактного суперкласса. Интерфейсы позволяют определять только поведение, а не реализацию, поэтому несколько классов могут реализовать один и тот же интерфейс, исключая возможность ромбовидного наследования. Абстрактный суперкласс может определять общую реализацию для всех подклассов, что также исключает ромбовидное наследование.
Что такое конструктор по умолчанию?
Конструктор - метод, вызываемый при создании экземпляра класса. Конструктор не имеет возвращаемого типа. Назначение - инициализировать поля объекта.
Если в классе конструктор не определен явно, то компилятор создает конструктор по умолчанию (default).
Если же в классе есть явно определенный конструктор, то default конструктор не создается, и, если он необходим, его нужно описывать явно.
Могут ли быть приватные конструкторы? Для чего они нужны?
Приватный (помеченный ключевым словом private, скрытый) конструктор может использоваться публичным статическим методом генерации объектов данного класса.
Также доступ к нему разрешен вложенным классам и может использоваться для их нужд запрещает создание экземпляра класса вне методов самого класса, например, чтобы гарантировать существование только одного объекта определённого класса, предположим какого-то ресурса, например БД.
Нужен для реализации паттернов, например singleton.
Расскажите про классы-загрузчики и про динамическую загрузку классов.
При запуске JVM, используются три загрузчика классов:
Динамическая загрузка происходит “на лету” в ходе выполнения программы с помощью статического метода класса Class.forName(имя класса).
Для чего нужна динамическая загрузка?
Например мы не знаем какой класс нам понадобится и принимаем решение в ходе выполнения программы передавая имя класса в статический метод forName().
Чем отличаются конструкторы по-умолчанию, конструктор копирования и конструктор с параметрами?
-У конструктора по умолчанию отсутствуют какие-либо аргументы.
-Конструктор копирования принимает в качестве аргумента уже существующий объект класса для последующего создания его клона.
-Конструктор с параметрами имеет в своей сигнатуре аргументы (обычно необходимые для инициализации полей класса).
Какие модификаторы доступа есть в Java? Какие применимы к классам?
private (приватный): члены класса доступны только внутри класса. Для обозначения
используется служебное слово private.
default, package-private, package level (доступ на уровне пакета): видимость класса/членов класса только внутри пакета. Является модификатором доступа по умолчанию – специальное обозначение не требуется.
protected (защищенный): члены класса доступны внутри пакета и в наследниках. Для
обозначения используется служебное слово protected.
public (публичный): класс/члены класса доступны всем. Для обозначения используется служебное слово public.
Последовательность модификаторов по возрастанию уровня закрытости: public-> protected->default->private.
Во время наследования возможно изменения модификаторов доступа в сторону большей видимости (для поддержания соответствия принципу подстановки Барбары Лисков).
Класс может быть объявлен с модификатором public и default.
Может ли объект получить доступ к члену класса объявленному как private?
Если да, то каким образом?
Что означает модификатор static?
Статическая переменная - это переменная, принадлежащая классу, а не объекту.
А статический класс- это вложенный класс, который может обращаться только к статическим полям обертывающего его класса.
Внутри static метода нельзя вызвать не статический метод по имени класса.
К каким конструкциям Java применим модификатор static?
Может ли статический метод быть переопределён или перегружен?
Нельзя переопределять статические методы.
Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса вместо переопределения. Это явление известно как сокрытие методов (hiding methods).
Дело в том, что Java позволяет вызывать статический метод на экземпляре класса. Однако, по факту реализация метода будет выбрана не из типа объекта, а из типа переменной, которая держит ссылку на этот объект.
Перегружен - да. Всё работает точно так же как и с обычными методами - 2 статических метода могут иметь одинаковое имя, если количество их параметров или типов различается.
Могут ли нестатические методы перегрузить статические?
Да. Это будут просто два разных метода для программы. Статический будет доступен по имени класса.
Можно ли сузить уровень доступа/тип возвращаемого значения при переопределении метода?
При переопределении метода нельзя сузить модификатор доступа к методу (например, с public до private), но можно расширить.
Изменить тип возвращаемого значения нельзя, но можно сузить возвращаемое значение, если они совместимы. Например, если метод возвращает объект класса, а переопределенный метод возвращает класс-наследник.
Что можно изменить в сигнатуре метода при переопределении?
Можно ли менять модификаторы (throws и тп)?
В сигнатуре(имя + параметры) менять ничего нельзя.
Возможно расширение уровня доступа.
Изменять тип возвращаемого значения при переопределении метода разрешено только в сторону сужения типа (вместо родительского класса - наследника).
Секцию throws метода можно не указывать, но стоит помнить, что она остаётся действительной, если уже определена у метода родительского класса.
Так же, возможно добавлять новые исключения, являющиеся наследниками от уже объявленных или исключения RuntimeException. Порядок следования таких элементов при переопределении значения не имеет.
Могут ли классы быть статическими?
Класс можно объявить статическим за исключением классов верхнего уровня.
Такие классы известны как «вложенные статические классы» (nested static class).
Что означает модификатор final? К чему он может быть применим?
Модификатор final может применяться к переменным, параметрам методов, полям и методам класса или самим классам.