ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 01.12.2023

Просмотров: 481

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
без аргументов. Абстрактные конструкторы будут часто использоваться для обеспечения ограничений класса или инвариантов, таких как минимальные поля, необходимые для настройки класса.
Что такое интерфейсы? Какие модификаторы по умолчанию имеют поля и
методы интерфейсов?
Интерфейс – это совокупность методов, определяющих правила взаимодействия элементов системы. Другими словами, интерфейс определяет как элементы будут
взаимодействовать между собой.
Ключевое слово interface используется для создания полностью абстрактных классов.
Основное предназначение интерфейса – определять, каким образом можно использовать класс, который его реализует. Создатель интерфейса определяет имена методов, списки аргументов и типы возвращаемых значений, но не реализует их поведение. Все методы неявно объявляются как public.
Интерфейс также может содержать и поля. В этом случае они автоматически являются публичными public, статическими static и неизменяемыми final.
Интерфейс нужен чтобы реализовать абстрактный класс. По сути это абстрактный класс, все методы у него абстрактные.

методы интерфейса являются публичными (public) и абстрактными (abstract),
если имплементироть интерфейс, то наследующий его класс должен будет реализовать все эти абстрактные методы, в отличии от абстрактного класса;

поля – public static final;

есть дефолтный метод;

нужно обязательно прописывать static;

методы могут быть static.
После 8-й Java появились дефолтные методы – если много классов реализуют данный интерфейс и чтобы не переписывать новый метод, используется дефолтный. Т. е., чтобы избежать ромбовидное наследование, нужно переопределить этот метод. А если в одном есть дефолтный метод, а в другом нет дефолтного и нужно имплементиться от обоих, то нужно всегда переопределять дефолтный.
Чем интерфейсы отличаются от абстрактных классов? В каких случаях
следует использовать абстрактный класс, а в каких интерфейс?
1. Интерфейс описывает только поведение (методы) объекта, а вот состояний (полей) у него нет (кроме public static final), в то время как у абстрактного класса они могут быть.
2. Можно наследовать только один класс, а реализовать интерфейсов сколько угодно.
Интерфейс может наследовать (extends) другой интерфейс/интерфейсы.
3. Абстрактные классы используются, когда есть отношение «is-a», то есть класс- наследник расширяет базовый абстрактный класс, а интерфейсы могут быть
реализованы разными классами, вовсе не связанными друг с другом.
4. Абстрактный класс может реализовывать методы; интерфейс может реализовывать статические методы начиная с 8-й версии.
5. Нет конструктора у интерфейса.


В Java класс может одновременно реализовать несколько интерфейсов, но наследоваться только от одного класса.
Абстрактные классы используются только тогда, когда присутствует тип отношений «is a»
(является). Интерфейсы могут реализоваться классами, которые не связаны друг с другом.
Абстрактный класс – средство, позволяющее избежать написания повторяющегося кода,
инструмент для частичной реализации поведения.
Интерфейс – это средство выражения семантики класса, контракт, описывающий возможности. Все методы интерфейса неявно объявляются как public abstract или (начиная с
Java 8) default-методами с реализацией по умолчанию, а поля – public static final.
Интерфейсы позволяют создавать структуры типов без иерархии.
Наследуясь от абстрактного, класс «растворяет» собственную индивидуальность. Реализуя интерфейс, он расширяет собственную функциональность.
Абстрактные классы содержат частичную реализацию, которая дополняется или расширяется в подклассах. При этом все подклассы схожи между собой в части реализации,
унаследованной от абстрактного класса и отличаются лишь в части собственной реализации абстрактных методов родителя. Поэтому абстрактные классы применяются в случае построения иерархии однотипных, очень похожих друг на друга классов. В этом случае наследование от абстрактного класса, реализующего поведение объекта по умолчанию может быть полезно, так как позволяет избежать написания повторяющегося кода. Во всех остальных случаях лучше использовать интерфейсы.
Что имеет более высокий уровень абстракции – класс, абстрактный класс
или интерфейс?
Интерфейс.
Может ли один интерфейс наследоваться от другого? От двух других?
Да, может. Используется ключевое слово extends.
Что такое дефолтные методы интерфейсов? Для чего они нужны?
В JDK 8 была добавлена такая функциональность, как методы по умолчанию с модификатором default. И теперь интерфейсы могут иметь их реализацию по умолчанию,
которая используется, если класс, реализующий данный интерфейс, не реализует метод.
Это нужно для обратной совместимости.
Если один или несколько методов добавляются к интерфейсу, все реализации также будут вынуждены их реализовывать. Методы интерфейса по умолчанию являются эффективным способом решения этой проблемы.
Почему в некоторых интерфейсах вообще не определяют методов?
Это так называемые маркерные интерфейсы. Они просто указывают, что класс относится к определенному типу. Примером может послужить интерфейс Clonable, который указывает на то, что класс поддерживает механизм клонирования.
Что такое static метод интерфейса?
Статические методы интерфейса похожи на методы по умолчанию, за исключением того, что для них отсутствует возможность переопределения в классах, реализующих интерфейс.


Статические методы в интерфейсе являются частью интерфейса без возможности использовать их для объектов класса реализации.
Методы класса java.lang.Object нельзя переопределить как статические.
Статические методы в интерфейсе используются для обеспечения вспомогательных методов, например, проверки на null, сортировки коллекций и т. д.
Как вызывать static метод интерфейса?
Используя имя интерфейса:
Paper.show();
Почему нельзя объявить метод интерфейса с модификатором final?
В случае интерфейсов указание модификатора final бессмысленно, т. к. все методы интерфейсов неявно объявляются как абстрактные, т. е. их невозможно выполнить, не реализовав где-то еще, а этого нельзя будет сделать, если у метода идентификатор final.
Как решается проблема ромбовидного наследования при наследовании
интерфейсов при наличии default-методов?
Обязательным переопределением default-метода.
В случае, если вызывается default-метод из интерфейса, его обязательно надо будет переопределить.
1   ...   4   5   6   7   8   9   10   11   ...   25

Каков порядок вызова конструкторов инициализации с учетом иерархии
классов?
Сначала вызываются все статические блоки в очередности от первого статического блока корневого предка и выше по цепочке иерархии до статических блоков самого класса.
Затем вызываются нестатические блоки инициализации корневого предка, конструктор корневого предка и так далее вплоть до нестатических блоков и конструктора самого класса.
При создании объекта производного класса конструкторы вызываются в порядке вниз по
иерархии наследования классов, т. е. начиная с самого базового класса и заканчивая производным классом.
Зачем нужны и какие бывают блоки инициализации?
Блоки инициализации представляют собой код, заключенный в фигурные скобки и размещаемый внутри класса вне объявления методов или конструкторов.
Существуют статические и нестатические блоки инициализации.
Блок инициализации выполняется перед инициализацией класса загрузчиком классов или созданием объекта класса с помощью конструктора.
Несколько блоков инициализации выполняются в порядке следования в коде класса.
Блок инициализации способен генерировать исключения, если их объявления перечислены в throws всех конструкторов класса.
Блок инициализации возможно создать и в анонимном классе.
Используются для выполнения кода, который должен выполняться один раз при
инициализации класса.

Для чего используются статические блоки инициализации?
Статические блоки инициализация используются для выполнения кода, который должен
выполняться один раз при инициализации класса загрузчиком классов в момент,
предшествующий созданию объектов этого класса при помощи конструктора. Такой блок принадлежит только самому классу.
Где разрешена инициализация статических/нестатических полей?
Статические поля можно инициализировать при объявлении, в статическом или нестатическом блоке инициализации.
Нестатические поля можно инициализировать при объявлении, в нестатическом блоке инициализации или в конструкторе.
Что произойдет, если в блоке инициализации возникнет исключительная
ситуация?
Для нестатических блоков инициализации, если выбрасывание исключения прописано явным образом, требуется, чтобы объявления этих исключений были перечислены в throws всех конструкторов класса (в контракте конструктора). Иначе будет ошибка компиляции.
В остальных случаях взаимодействие с исключениями будет проходить так же, как и в любом другом месте. Класс не будет инициализирован, если ошибка происходит в статическом блоке, и объект класса не будет создан, если ошибка возникает в нестатическом блоке.
Для статического блока выбрасывание исключения в явном виде приводит к ошибке компиляции ExceptionInizialazionError.
Какое исключение выбрасывается при возникновении ошибки в блоке
инициализации класса?
Если возникшее исключение – наследник Error:

для
статических блоков инициализации будет выброшено
java.lang.ExceptionInInitializerError;

для нестатических будет проброшено исключение-источник.
Если возникшее исключение – наследник Error, то в обоих случаях будет выброшено
java.lang.Error.
Если исключение java.lang.ThreadDeath (смерть потока), то в этом случае никакое исключение выброшено не будет.
Что такое класс Object?
Все классы являются наследниками суперкласса Object. Это не нужно указывать явно. В
результате объект Object может ссылаться на объект любого другого класса.
Какие методы есть у класса Object (перечислить все)? Что они делают?
Object – это базовый класс для всех остальных объектов в Java. Любой класс наследуется от
Object и, соответственно, наследуют его методы:

public boolean equals(Object obj) – служит для сравнения объектов по значению;

int hashCode() – возвращает hash-код для объекта;



String toString() – возвращает строковое представление объекта;

Class getClass() – возвращает класс объекта во время выполнения;

protected Object clone() – создает и возвращает копию объекта;

void notify() – возобновляет поток, ожидающий монитор;

void notifyAll() – возобновляет все потоки, ожидающие монитор;

void wait() – остановка вызвавшего метод потока до момента, пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

void wait(long timeout) – остановка вызвавшего метод потока на определенное время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

void wait(long timeout, int nanos) – остановка вызвавшего метод потока на определенное время или пока другой поток не вызовет метод notify() или notifyAll()
для этого объекта;

protected void finalize() – может вызываться сборщиком мусора в момент удаления объекта при сборке мусора.
Расскажите про equals и hashcode
Хеш-код –это целочисленный результат работы метода, которому в качестве входного параметра передан объект. Рассчитывается по нативному методу.
Equals – это метод, определенный в Object, который служит для сравнения объектов. При
сравнении объектов при помощи == идет сравнение по ссылкам. При сравнении по
equals() идет сравнение по состояниям объектов (по умолчанию случайным образом, но есть другие варианты).
По умолчанию ссылки, чтобы его использовать, нужно переопределить (на область в памяти), т. к. при == сравниваются ссылки, а equals сравнивает состояния:
Свойства equals():

Рефлексивность: для любой ссылки на значение x, x.equals(x) вернет true;

Симметричность: для любых ссылок на значения x и y, x.equals(y) должно вернуть true, тогда и только тогда, когда y.equals(x) возвращает true.

Транзитивность: для любых ссылок на значения x, y и z, если x.equals(y) и y.equals(z) возвращают true, тогда и x.equals(z) вернет true;

Непротиворечивость: для любых ссылок на значения х и у, если несколько раз вызвать х.equals(y), постоянно будет возвращаться значение true либо постоянно будет возвращаться значение false при условии, что никакая информация,
используемая при сравнении объектов, не поменялась;

Совместимость с hashCode(): два тождественно равных объекта должны иметь одно и то же значение hashCode().
При переопределении equals() обязательно нужно переопределить метод hashCode().
Равные объекты должны возвращать одинаковые хэш коды.

Каким образом реализованы методы hashCode() и equals() в классе Object?
1. Реализация метода Object.equals() сводится к проверке на равенство двух ссылок:
public boolean equals(Object obj) {
return (this == obj);
}
2. Реализация метода Object.hashCode() описана как native, т. е. определенной не с помощью Java-кода и обычно возвращает адрес объекта в памяти:
public native int hashCode();
Зачем нужен equals(). Чем он отличается от операции ==?
Метод equals() определяет отношение эквивалентности объектов.
При сравнение объектов с помощью == сравнение происходит лишь между ссылками.
При сравнении по переопределенному разработчиком equals() – по внутреннему состоянию объектов.
Правила переопределения метода Object.equals()

Использование оператора == для проверки, является ли аргумент ссылкой на указанный объект. Если является, возвращается true. Если сравниваемый объект
== null, должно вернуться false.

Использование оператора instanceof и вызова метода getClass() для проверки,
имеет ли аргумент правильный тип. Если не имеет, возвращается false.

Приведение аргумента к правильному типу. Поскольку эта операция следует за проверкой instanceof она гарантированно будет выполнена.

Обход всех значимых полей класса и проверка того, что значение поля в текущем объекте и значение того же поля в проверяемом на эквивалентность аргументе соответствуют друг другу. Если проверки для всех полей прошли успешно,
возвращается результат true, в противном случае – false.

По окончанию переопределения метода equals() следует проверить: является ли порождаемое отношение эквивалентности рефлексивным, симметричным,
транзитивным и непротиворечивым? Если ответ отрицательный, метод подлежит соответствующей правке.
Что будет, если переопределить equals(), не переопределяя hashCode()?
Какие могут возникнуть проблемы?
Классы и методы, которые используют правила этого контракта, могут работать некорректно.
Так для HashMap это может привести к тому, что пара «ключ-значение», которая была в нее помещена, при использовании нового экземпляра ключа не будет в ней найдена.
Какой контракт между hashCode() и equals()?
1. Если два объекта возвращают разные значения hashcode(), то они не могут быть равны.
2. Если equals объектов true, то и хеш-коды должны быть равны.