• ,

Java. Справочное руководство для интервью - Часть 1. (Перевод статьи)

Исходная статья находится по адресу:
http://www.javacodegeeks.com/2014/02/java-interview-reference-guide-part-1.html

Опубликовал: Nitin Kumar, в Core Java, 3 февраля 2014 г

Java. Объектно-Ориентированная концепция.


Java основывается на объектно-ориентированной концепции, которая дает более высокий уровень абстракции для решения любой проблемы реальным способом.

Объектно-Ориентированный подход концептуализирует решение проблемы в объектах реального мира, которые проще повторно использовать в приложениях. Например: стул, вентилятор, собака, компьютер и т.д.

В Java, класс — это документация, шаблон или прототип, который определяет общее поведение объектов того же вида. Экземпляр является реализацией определенного класса, и все экземпляры класса имеют аналогичные свойства, как представлено в описании класса. Например, вы можете определить класс, который называется Дом, с числом комнат, как атрибутом, и создать объекты: дом с 2 комнатами, дом с 3 комнатами и т.д.

Преимущества:

Ниже перечислено несколько преимуществ разработки объектно-ориентированного программного обеспечения:

  • Меньше затрат на обслуживание, главным образом благодаря модульности.
  • Код легче повторно использовать за счет таких функций, как наследование, что как следствие ускоряет разработку.
  • Повышается надежность и гибкость кода.
  • Код легче понять, это обусловлено моделированием реального мира.
  • Лучшая абстракция на объектном уровне.
  • Уменьшение сложности перехода от одной стадии разработки к другой.

Существуют четыре основных понятия ООП:

  • Инкапсуляция
  • Наследование
  • Полиморфизм
  • Абстракция

Инкапсуляция:

Инкапсуляция представляет собой правила для других объектов, которые указывают, какие элементы скрыты, а какие открыты для доступа другим объектам. В Java мы используем модификатор доступа private для того, чтобы скрыть метод и ограничить доступ к переменной из внешней среды. Java также предусматривает различные модификаторы доступа, такие как public, который устанавливается по-умолчанию, protected и private, которые используются для ограничения видимости на различных уровнях, но конечная цель инкапсуляции — это скрыть те элементы, которые не должны изменяться. На практике лучше всего, когда класс имеет только одну причину для изменения, и инкапсуляция реализует принципы проектирования этой «одной причины».

На практике, в Инкапсуляции предполагается сокрытие методов, чтобы избежать нарушения работы других классов.

Преимущества:


Ниже перечислены несколько преимуществ инкапсуляции:

  • Вы можете защитить внутреннее состояние объекта, скрывая его атрибут.
  • Это повышает модульность кода, предотвращая взаимодействия между объектами самым неожиданным образом.
  • Увеличивается удобство использования.
  • Поддерживаются условия конкретного объекта.
  • Инкапсуляция облегчает поддержку ПО
  • Изменения кода могут быть независимыми

Полиморфизм:

Полиморфизм — это способность (в программировании) представить тот же интерфейс для различных форм (типов данных), лежащих в основе. Это означает, что классы имеют различную функциональность, несмотря на то, что используют общий интерфейс и могут быть вызваны динамически через специальную ссылку класса.

Классическим примером является класс Shape (фигура), и все классы, которые могут наследоваться от него (квадрат, круг, додекаэдр, неправильный многоугольник, знак и т.д.).

В этом примере, каждый класс будет иметь свою собственную функцию Draw() и клиентский код может выполнять следующие действия:

Shape shape = new Square();
Shape.area()  чтобы получить корректное поведение для любой формы.


Прелесть полиморфизма в том что код работает с различными классами и нет необходимости знать какой класс его использует, т.к. все они работают по одному принципу.

Процесс, используемый Объектно-Ориентированными языками программирования, реализующий динамический полиморфизм, называется динамическим связыванием.

Примечание: Полиморфизм — это возможность выбора более специализированных методов в зависимости от выполнения вызванного объекта. Полиморфизм так же может использоваться без участия каких-либо абстрактных классов.

Преимущества:

  • Создается код, используемый повторно: это значит, что если однажды созданы классы, реализованы и протестированы, то они могут быть легко использованы, не заботясь о том, что написано в классе.
  • Это обеспечивает более общий и слабосвязанный код.
  • Время компиляции значительно уменьшается, а разработка становится быстрее.
  • Динамическое связывание: Один и тот же интерфейс может быть использован для создания методов с различными реализациями.
  • Полная реализация может быть заменена с помощью сигнатуры метода.

Переопределение метода для достижения Полиморфизма: Переопределение интерфейсов с двумя методами: Один в родительском классе, а другой в дочернем классе с такими же именами и сигнатурами.

Переопределение позволяет определить ту же самую операцию по-разному для разных типов данных

Например:

while(it.hasNext())
{
    Shape s = (Shape) it.next();
    totalArea += s.area(dim);  //полиморфический вызов метода. Будет вызван правильный объект. 
}




Перегрузка метода или Специальный полиморфизм или статический полиморфизм:

Перегрузка интерфейсов с несколькими методами в том же классе с тем же именем, но с другим телом метода. Перегрузка метода позволяет определить ту же операцию по-разному для различных данных. Какое-то время она называлась статическим полиморфизмом, но на самом деле это не полиморфизм.

Перегрузка методов является не более чем двумя методами, с одинаковыми именами, но различными списками аргументов. Она не имеет ничего общего с наследованием и полиморфизмом. Перегруженный метод, это не то же самое, что и переопределенный метод. [Глава первая Java]

Параметрический полиморфизм с использованием дженериков в Java:

При объявлении класса, имя поля можно связать с различными типами и имя метода так же можно ассоциировать с различными параметрами и возвращаемыми типами. Java поддерживает параметрический полиморфизм с использованием дженериков.
Примером является список, который может принимать тип данных, содержащих дженереки.

List<String> list = new ArrayList<String>();


Почему мы не можем переопределить статический метод в Java?


Переопределение зависит от наличия экземпляра класса. Смысл полиморфизма заключается в том, что вы можете создать подкласс класса и объект реализует этот подкласс, будет разное поведение одних и тех же методов, определенных в суперклассе (или переопределенных в подклассе). Статический метод не связан с каким-либо экземпляром класса, так что это понятие к нему не применяется.

Ранее выдвигались две основные идеи, продвижения разработки на Java, которые повлияли на неё. Одна из них — это отношение к производительности: было много критики со стороны Smalltalk о том, что JVM работала слишком медленно (из-за сбора мусора и полиморфных вызовов, которые были частью этой причины) и разработчики Java были вынуждены исправить это. Другая состояла в том, что целевая аудитория для Java — это были разработчики C++. Вызов статических методов устроен знакомым для программистов C++ образом и работает так же быстро, потому что нет пути вверх по иерархии классов, и чтобы выяснить, какой метод нужно вызвать, ты отправляешься прямо в класс и вызываешь указанный метод. [Stack overflow]

Наследование:

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

Унаследованный класс расширяет функциональность приложения, повторно используя родительское поведение и добавляя новую функциональность. Это сделает проектирование плотно связанным, потому что если вы хотите изменить суперкласс, вы должны знать все детали подклассов, чтобы избежать поломки приложения.

Это форма повторного использования ПО, когда новый класс (подкласс) создается из уже существующего класса (суперкласса) и расширяет свою функциональность, при этом используя некоторые свойства суперкласса.

Итак, если у вас есть класс-родитель, а потом у вас появляется класс-наследник, то наследник наследует все сущности, которыми обладает родитель.

Преимущества:

  • Легче повторно использовать код
  • Устанавливается логическое отношение «Является кем-то», Например: Собака является животным.
  • Код становится модульным
  • Позволяет избегать дублирования

Недостатки:

  • Тесная связь: подкласс зависит от реализации родительского класса, что делает код тесно связанным.

Абстракция:

Абстракция представляет собой разработку класса из условий интерфейсов и их функциональности, не учитывая детали их реализации. Абстрактный класс включает интерфейсы без фактической реализации. Он отделяет реализацию объекта от поведения или реализации. Абстракция упрощает разработку, скрывая несущественные детали.

Преимущества:

  • При использовании абстракции, мы можем выделить объекты, которые могут быть сгруппированы в другой тип.
  • Часто изменения свойств или методов могут быть сгруппированы в отдельный тип, причем главный тип останется без изменений. Это усиливает принцип Объектно-Ориентированного Анализа и Дизайна — «Код должен быть открыт для расширения, но закрыт для модификации».
  • Упрощает представление моделей предметной области.

Различия между абстракцией и инкапсуляцией

Инкапсуляция — это стратегия, используемая в рамках абстракции. Инкапсуляция относится к состоянию объектов — объекты инкапсулируют свое состояние и скрывают его от доступа извне; снаружи пользователи класса могут взаимодействовать с его методами, но не могут получить доступ к составляющим класса напрямую. Таким образом класс абстрагирует детали реализации, относящиеся к его состоянию.

Абстракция — это более общий термин; ее так же можно достигнуть путем использования подклассов (среди прочих). Например, список классов в стандартной библиотеке — это абстракция для последовательности элементов, проиндексированных по их позиции, конкретными примерами List'а будут ArrayList или LinkedList. Код, который взаимодействует со списком абстракций более детален, чем вид используемого списка. [Stack overflow]

Абстракция часто невозможна, без скрытия инкапсуляцией деталей, лежащих в основе — если класс предоставляет свое внутреннее состояние, он не может изменить свою внутреннюю работу, и, следовательно, не может абстрагироваться.

Что такое абстрактный класс и абстрактный метод?

В проектировании, вы хотите, чтобы базовый класс представлял только интерфейс для своих производных классов. Это значит, вы не хотите, чтобы кто-нибудь создавал экземпляр объекта этого класса. Вы только хотите, чтобы было приведение к типу (неявное приведение к базовому типу, которое дает вам полиморфное поведение), так что этот интерфейс может быть использован. Это достигается путем указания класса абстрактным, при этом используется ключевое слово abstract.

Существуют некоторые ограничения: нельзя создать экземпляр абстрактного класса, следует использовать только тот класс, который реализует абстрактные методы. И обеспечивает полиморфизм.

Абстрактный класс может содержать как абстрактные методы, так и конкретные методы. В классе, если один метод объявлен абстрактным, класс должен быть объявлен абстрактным. Однако, обратное не всегда верно. Если класс объявлен как абстрактный, он может не иметь абстрактных методов в нем.

Если метод не обеспечивает фактическую реализацию, но обеспечивает сигнатуру метода, он называется абстрактным методом. Фактическая реализация возлагается на подклассы, которые расширяют абстрактный класс.

Абстрактный метод не может быть реализован; только другой класс может наследоваться от него.

Когда используется абстрактный класс?

Абстрактные классы помогают определить некоторые типы поведения по умолчанию и обеспечить подклассам какое-то конкретное поведение.

Например: List — это интерфейс, в то время как AbstractList реализует поведение по умолчанию List'а, который может быть использован как есть или может быть реализован в подклассе, например как ArrayList.

Что такое Интерфейс?

Ключевое слово interface перенимает концепцию абстрактного класса дальше, препятствуя реализации любого метода или функции для всех. Вы можете только объявить метод или функцию, но не обеспечить реализацию. Класс, который реализует интерфейс, должен обеспечивать фактическую реализацию. Интерфейс является крайне эффективным и широко используемым аспектом в Объектно-Ориентированном проектировании, так как он обеспечивает разделение интерфейса и реализации, и позволяет:

Преимущества интерфейсов:

  • Множественное наследование
  • Свободные парно-определенные абстракции операций, как отдельный тип реализации, могут быть чем угодно: JDBC, JPA, JTA, и т.д.
  • Интерфейс программы не реализуется.
  • Полиморфизм с динамическим связыванием — выявляет объект программного интерфейса, не раскрывая его фактической реализации.
  • Абстрактный уровень: Проблемы разделения

Разница между интерфейсом и абстрактным классом:

  • Интерфейс представляет собой соглашение, по которому опрашиваются классы, реализующие интерфейс, как они определяют этот интерфейс. Это пустая оболочка с объявлением метода.
  • Абстрактный класс определяет некоторое общее поведение и задает подклассу свойство определить редкое или специфичное поведение для этого класса.
  • Методы и члены абстрактного класса могут быть определены с любым типом видимости, в то время как все методы интерфейсов должны быть определены как public.
  • При наследовании от абстрактного класса, дочерний класс должен определить абстрактные методы, в то время как интерфейс может расширять другой интерфейс и методы не должны быть определены.
  • Дочерний класс может наследоваться только от одного абстрактного (или любого другого) класса, в то время как интерфейс или класс может наследоваться от нескольких других интерфейсов.
  • Дочерний класс может реализовать абстрактные методы с тем же самым или менее ограниченным уровнем видимости, в то время как класс, реализующий интерфейс должен определить методы с тем же уровнем видимости.
  • Интерфейс не может содержать конструкторы, в отличии от Абстрактного класса.
  • Переменные, объявленные в интерфейсе Java по умолчанию имеют модификатор доступа final. Абстрактный класс может содержать переменные не только с модификатором final.
  • Методы интерфейса в Java имеют модификатор доступа public по умолчанию. Абстрактный класс в Java может иметь обычные модификаторы доступа, такие как private, protected и т.д.

Композиция:

Возможность многократного использования кода может быть достигнута благодаря реализации наследования или композиции, но композиционный подход к повторному использованию кода обеспечивает более сильную инкапсуляцию, чем наследование, потому что изменение back-end класса не должно разрушить код, который полагается только на front-end класс.

Композиция — это методика проектирования для реализации существующих связей в классах. Мы можем использовать наследование Java или композицию для повторного использования кода.

Композиция выражает связи между объектами. Например, представьте стул. Стул имеет сиденье. Стул имеет спинку. И имеет набор ножек. Фраза «имеет» подразумевает отношения, где стул владеет чем-либо, или как минимум, он использует другой предмет. Именно такие отношения вида «Имеет» и являются основой для составления композиции.

Преимущества:

Композиция (иметь)Наследование (являться)
1Поддерживает полиморфизм и повторное использование кодаПоддерживает полиморфизм и повторное использование кода
2Объект создается во время работыОбъект создается динамически во время компиляции
3Реализация может быть изменена во время выполненияРеализация может быть изменена во время выполнения
4Подкласс не зависит от родительского класса, что способствует ослаблению связей (в частности, в интерфейсе управления)Подкласс зависит от реализации родительского класса, поэтому они плотно связаны
5Используется, например, когда в Доме есть Ванная. Некорректно говорить, что Дом — это Ванная.Наследование является однонаправленным. Например: Дом это Здание. Но Здание не обязательно является Домом.

Примечание: Не используйте наследование только для того, чтобы получить возможность повторно использовать код. Если нет отношения типа «являться» между классами, то нужно использовать композиция для повторного использования кода.

Различия между Композицией и Агрегацией в отношениях объектов

Агрегация: Агрегация представляет собой объединение, в котором один класс принадлежит коллекции. Он является частью целого в отношениях, где часть может существовать без целого. Это слабые отношения. Нет циклической зависимости. Например: заказ и продукт.

Композиция: Композиция представляет собой объединение, в котором один класс принадлежит коллекции. Он является частью целого, где часть не может существовать без целого. Если в целое удаляется, то и все части будут так же удалены. Эти отношения сильнее. Примером могут служить: Полигон и точки, заказ и порядок заказа.

Ссылки:

4 комментария

Marchello
Разве по-умолчанию устанавливается не default (package-private), видимость внутри пакета?
mrANDERSON
  • mrANDERSON
  • 0
  • Комментарий отредактирован 2015-11-10 21:15:41 пользователем mrANDERSON
package по сути. Но само слово не пишется.
Marchello
Да, я в курсе. Просто выше (где инкапсуляция) написано, что public — модификатор по-умолчанию
mrANDERSON
Может имеется ввиду, что он ИДЕ-ешками ставиться по-умолчанию..))
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.