Как старший член моей организации, я должен регулярно проходить собеседования в рамках процесса подбора персонала нашей компании. Как интервьюер, я был свидетелем некоторых интересных наблюдений о Java и знаниях отдельных респондентов. Диапазон опыта интервьюируемых варьируется от трех до восьми лет.
Во многих случаях я заметил, что кандидат очень хорошо знает эту тему. Их теоретические знания очень хороши. И качество их ответов показывает, что у них был практический опыт работы в различных областях ядра Java, таких как обработка исключений, структура коллекций, обобщения и объекты. У них есть более или менее четкое представление о том, что это за вещи. И во многих случаях им известны новые функции, добавленные в более поздние версии.
Вам также может понравиться:
Системный подход к написанию лучшего кода с концепциями ООП
Однако, как интервьюер, первое наблюдение, которое я сделал, заключается в том, что разработчики часто демонстрируют недостаток четких знаний о том, почему они использовали эти функции в своих программах или проектах. Похоже, им не хватает количества преимуществ, которые они могут получить от использования указанных функций, или, если бы они не использовали эту функцию, с какими проблемами или трудностями они столкнулись бы в противном случае.
Эта неосведомленность проистекает из непонимания многих ключевых областей Java, таких как структура коллекций, полиморфизм, интерфейсы и даже обработка исключений.
В этой статье я собираюсь обсудить две основные особенности Java — полиморфизм и интерфейсы.
Полиморфизм
Поскольку полиморфизм является одним из ключевых принципов объектно-ориентированного программирования, вокруг этой темы всегда будут возникать вопросы.
В интервью я обычно спрашиваю: «что такое полиморфизм?»
И удивительно, что в большинстве случаев, ответ получил: « р olymorphism означает множество форм .»
В ответ на следующий вопрос , как правило: « W шляпа вы имеете в виду под» много форм?»
Затем, где вещи становятся интересными. С этого момента я обнаружил, что понятие «много форм» варьируется от кандидата к кандидату .
Наиболее распространенный ответ, который я получил, был: « Существует два типа полиморфизма — полиморфизм во время выполнения и статический полиморфизм. Переопределение метода является примером полиморфизма во время выполнения, а перегрузка метода — примером статического полиморфизма».
Очевидно, они знают, почему переопределение метода называется «полиморфизмом времени выполнения» и почему «перегрузка метода» называется «статическим полиморфизмом». Но из этих ответов трудно прийти к выводу о том, что они имели в виду под «многими формами». И хотя перегрузка метода и переопределение метода — полиморфизм, почему они — полиморфизм?
Следующим наиболее распространенным ответом на этот вопрос было: « Позвольте мне объяснить на примере …» И пример, используемый для объяснения этого, опять же, тот же пример перегрузки метода и переопределения метода, который описан ранее.
Однако в очень немногих случаях кандидат использует концепцию ссылки на объект для объяснения полиморфизма. По сути, лучшим использованием полиморфизма в Java является возможность ссылаться на дочерний класс с помощью ссылки на родительский класс. В полиморфизме «много форм» означает способность объекта или метода принимать много форм. Переопределение метода и перегрузка метода в основном означают поведение в Java, которое позволяет разработчику воспользоваться этим принципом.
Ниже приведен пример:
На приведенной выше диаграмме Shape является интерфейсом (также может быть классом) с одним абстрактным методом draw()
. Треугольник, прямоугольник и круг — три реализации этого интерфейса. Каждая конкретная реализация имеет свой собственный процесс рисования.
Джава
1
Shape shape;
2
shape = new Triangle();
4
shape.draw();
5
shape = new Rectangle();
7
shape.draw();
8
shape = new Circle();
10
shape.draw();
Здесь, во-первых, создается ссылка на Shape Interface (или Class). Поскольку все три других класса реализуют (или расширяют) его, объект формы может ссылаться на любой из них, то есть он может принимать любую форму треугольника, прямоугольника или круга. И какой процесс рисования будет использоваться, который определяется во время выполнения, в зависимости от формы, которую Shape принял в тот момент, используя переопределение поведения метода в Java.
Интерфейс
Интерфейс - еще одна ключевая особенность Java, которая широко используется в разработке Java. В интервью, как правило, обсуждение интерфейсов начинается с простого вопроса: « Что такое интерфейс?»
Почти каждый кандидат дает ответ: « Интерфейс - это класс, который имеет только тело метода, но не имеет реализации. Любой класс, реализующий Интерфейс, должен определять или реализовывать свои собственные методы ».
Этот ответ верен только частично, если вы опытный программист на Java и использовали интерфейсы в своей программе.
После получения вышеуказанного ответа я задаю следующие вопросы: « Какое использование интерфейса? Какие преимущества мы получим от использования интерфейса? И с какими недостатками мы столкнемся, если у нас его не будет? »
Здесь наиболее распространенный ответ заключается в том, что когда поведение конкретной функциональности меняется от объекта к объекту, то для создания суперкласса используется интерфейс, и создаются различные подклассы, расширяющие суперкласс, и каждый подкласс реализует свое поведение. , И вышеупомянутые (форма, треугольник, прямоугольник и круг) или (животное, собака, слон) приводятся в качестве примера. Где Shape или Animal - это суперкласс, реализующий некоторый Интерфейс, а подклассы расширяют этот суперкласс и реализуют это конкретное поведение.
Другое использование, предоставляемое многими кандидатами, - реализация множественного наследования с использованием интерфейсов в Java, что в противном случае невозможно.
Оба приведенных выше ответа верны. Но дело в том, что первый случай может быть выполнен даже без интерфейсов или просто путем создания суперкласса и расширения этого класса различными подклассами. Большинство кандидатов, с которыми я брал интервью, застряли на этом. Даже если мы можем сделать это без реализации интерфейса, зачем мне его использовать?
Если мы следуем документации Oracle, во введении Интерфейсов это говорит:
«В разработке программного обеспечения существует ряд ситуаций, когда разрозненным группам программистов важно согласиться на« контракт », в котором прописано, как взаимодействует их программное обеспечение. Каждая группа должна иметь возможность писать свой код, не зная, как другие Код группы написан. Вообще говоря,
интерфейсы - это такие контракты. "
Давайте обсудим эти вопросы один за другим.
По сути, Интерфейс - это контракт, которому разработчик должен следовать при его реализации. В нем говорится, что когда вы реализуете что-то, вы должны предоставить данный набор функций, иначе вы будете неполными. Здесь неполный означает, что класс не является полным (например, абстрактный класс).
Вот пример:
Джава
xxxxxxxxxx
1
public Interface Shape {
2
void draw();
3
}
Форма представляет собой интерфейс с только один метод, то есть draw()
. По сути, это контракт, когда вы реализуете этот интерфейс, вы должны реализовать функциональность рисования, иначе вы не полный класс. Поэтому для любого класса, такого как Triangle или Rectangle, когда мы реализуем этот интерфейс, они должны реализовать draw()
метод.
Еще одно преимущество - с точки зрения разработки программы - это идея «программирования для интерфейса, а не для реализации» . Это означает, что когда мы разрабатываем наш код, мы должны сосредоточиться на Интерфейсе или функциональных возможностях, которые предоставляет Интерфейс, а не на фактической реализации.
Хотя мы иногда используем ArrayList
, мы не так обеспокоены тем, как реализована функция, установленная интерфейсом списка ArrayList
. Нас интересуют только функции, предоставляемые интерфейсом List, что создает слабую связь в нашем коде.
Джава
xxxxxxxxxx
1
List l = new ArrayList();
2
l.add(xxx)
Если завтра нам нужно будет использовать LinkedList
вместо ArrayList
, мы могли бы легко сделать это, изменив:
List l = new LinkedList();
И мы не думаем о поведении ArrayList
используемых в нашей программе, потому что мы использовали их через контракт, опубликованный Интерфейсом.
Вывод
При изучении Java или любого другого языка программирования мы должны сосредоточиться не только на важных функциях, но и на том, зачем они нам нужны, и на дополнительных преимуществах от их использования. Если мы не видим какого-либо преимущества, мы должны переосмыслить, почему мы его даже используем.
Дальнейшее чтение
ООП для начинающих: что такое полиморфизм?