никакие libs не используются:
dict_format_string = "{'1':'one', '2' : 'two'}"
d = {}
elems = filter(str.isalnum,dict_format_string.split("'"))
values = elems[1::2]
keys = elems[0::2]
d.update(zip(keys,values))
ПРИМЕЧАНИЕ. Поскольку он имеет hardcoded split("'")
, он будет работать только для строк, где данные «одинарные».
Вы хорошо описали практические различия в использовании и реализации, но ничего не сказали о различии в значении.
Интерфейс - это описание поведения, которое будет иметь класс реализации. Класс реализации гарантирует, что он будет иметь эти методы, которые могут быть использованы на нем. Это в основном контракт или обещание, которое должен выполнить класс.
Абстрактный класс является основой для разных подклассов, которые разделяют поведение, которое не нужно многократно создавать. Подклассы должны выполнить поведение и иметь возможность переопределить предопределенное поведение (если оно не определено как final
или private
).
Вы найдете хорошие примеры в пакете java.util
, который включает интерфейсы, такие как List
и абстрактные классы, такие как AbstractList
, которые уже реализуют интерфейс. Официальная документация описывает AbstractList
следующим образом:
Этот класс обеспечивает скелетную реализацию интерфейса List для минимизации усилий, необходимых для реализации этого интерфейса при поддержке хранилище данных «произвольного доступа» (например, массив).
Из того, что я понимаю и как я подхожу,
Интерфейс подобен спецификации / контракту, любой класс, реализующий класс интерфейса, должен реализовать все методы, определенные в абстрактном классе (кроме методов по умолчанию ( введенный в java 8))
В то время как я определяю абстрактный класс, когда знаю реализацию, требуемую для некоторых методов класса и некоторых методов, я до сих пор не знаю, какова будет реализация (мы могли бы знать функцию но не реализация). Я делаю это так, чтобы позже в той части разработки, когда я знаю, как эти методы должны быть реализованы, я могу просто расширить этот абстрактный класс и реализовать эти методы.
Примечание. Вы не можете иметь тело функции в интерфейсе если метод не является статическим или по умолчанию.
Как насчет мышления следующим образом:
Итак, когда у вас есть абстрактный класс Mammals, подкласс Human и интерфейс Driving, вы можете сказать
. Мое предложение состоит в том, что фраза о знании книги указывает, что он хотел услышать семантическая разница между обоими (как и другие, которые уже предложены).
Я делаю интервью для работы, и я буду выглядеть неблагоприятно и на ваш ответ (извините, но я очень честен). Похоже, вы читали о различиях и пересматривали ответ, но, возможно, вы никогда не использовали его на практике.
Хорошее объяснение того, почему вы будете использовать каждый, может быть намного лучше, чем точное объяснение разницы. Работодатели ultimatley хотят, чтобы программисты делали вещи, которые не знают их, что трудно продемонстрировать в интервью. Ответ, который вы дали, был бы хорош, если бы вы претендовали на техническую или документационную работу, но не на роль разработчиков.
Желаем удачи в интервью в будущем.
Также мой ответ на этот вопрос вопрос скорее о технике собеседования, а не о техническом материале, предоставленном вами. Возможно, подумайте об этом. https://workplace.stackexchange.com/ может быть отличным местом для такого рода вещей.
В абстрактном классе вы можете написать стандартную реализацию методов! Но в интерфейсе вы не можете. В принципе, в интерфейсе существуют чистые виртуальные методы, которые должны быть реализованы классом, который реализует интерфейс.
Да, ваши ответы были технически правильными, но там, где вы поступили не так, не показывали их, вы понимаете, какие проблемы и недостатки вы выбираете друг за другом. Кроме того, они, вероятно, были обеспокоены / испугались совместимости своей кодовой базы с обновлениями в будущем. Этот тип ответа, возможно, помог (в дополнение к тому, что вы сказали):
«Выбор абстрактного класса над классом интерфейса зависит от того, что мы прогнозируем будущим кода.
Абстрактные классы обеспечивают лучшую совместимость вперед, потому что вы можете продолжить добавление поведения к абстрактному классу в будущее без нарушения существующего кода -> это невозможно с классом интерфейса.
С другой стороны, интерфейсные классы более гибкие, чем абстрактные классы. Это связано с тем, что они могут реализовать несколько интерфейсов . Дело в том, что Java не имеет множественных наследований, поэтому использование абстрактных классов не позволит вам использовать структура иерархии других классов ...
Итак, в конечном итоге хорошее общее правило: Предпочитаете использовать интерфейсные классы, если в вашей кодовой базе нет существующих / стандартных реализаций. И используйте абстрактные классы для сохранения совместимость, если вы знаете, что в будущем вы будете обновлять свой класс ».
blockquote>Удачи в следующем интервью!
Сначала я приведу вам пример:
public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}
Теперь предположим, что у вас есть 3 базы данных в вашем приложении. Затем каждая реализация для этой базы данных должна определять два вышеуказанных метода:
public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}
Но что, если encryptPassword () не зависит от базы данных, и для каждого класса одинаково? Вместо этого рассмотрим этот подход:
public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}
// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}
Теперь в каждом дочернем классе нам нужно реализовать только один метод - метод, который зависит от базы данных.
Я старался изо всех сил и надеюсь, что это очистит ваши сомнения.
Из того, что я понимаю, интерфейс, который состоит из конечных переменных и методов без реализаций, реализуется классом для получения группы методов или методов, связанных друг с другом. С другой стороны, абстрактный класс, который может содержать не конечные переменные и методы с реализациями, обычно используется в качестве руководства или как суперкласс, из которого наследуются все родственные или подобные классы. Другими словами, абстрактный класс содержит все методы / переменные, которые разделяются всеми его подклассами.
ваш ответ прав, но интервьюеру нужно, чтобы вы дифференцировались в соответствии с перспективой разработки программного обеспечения не в соответствии с деталями Java.
Простые слова:
Интерфейс подобен интерфейсу магазина все, что показано на нем, должно быть в магазине, поэтому любой метод в интерфейсе должен быть реализован в конкретном классе. Теперь, что, если некоторые классы имеют некоторые точные методы и варьируются в других. Предположим, что интерфейс посвящен магазину, который содержит две вещи, и предположим, что у нас есть два магазина, в которых есть спортивное снаряжение, но у одного есть одежда, а у другой есть обувь. Итак, что вы делаете, это сделать абстрактный класс для спорта, который реализует метод «Спорт» и не позволяет другому способу не реализовываться. Абстрактный класс здесь означает, что этот магазин не существует сам, но он является базой для других классов / магазинов. Таким образом, вы организуете код, избегаете ошибок репликации кода, унификации кода и обеспечения повторного использования другим классом.
Интерфейс - это «контракт», в котором класс, реализующий контракт, обещает реализовать методы. Примером, когда мне пришлось писать интерфейс вместо класса, было то, что я обновлял игру от 2D до 3D. Мне пришлось создать интерфейс для совместного использования классов между 2D и 3D-версией игры.
package adventure;
import java.awt.*;
public interface Playable {
public void playSound(String s);
public Image loadPicture(String s);
}
Затем я могу реализовать методы, основанные на среде, но все же могу называть эти методы от объекта, который не знает, какую версию игры загружается.
public class Adventure extends JFrame implements Playable
public class Dungeon3D extends SimpleApplication implements Playable
public class Main extends SimpleApplication implements AnimEventListener,
ActionListener, Playable
Как правило, в игровом мире мир может быть абстрактным классом, который выполняет методы на игра:
public abstract class World...
public Playable owner;
public Playable getOwner() {
return owner;
}
public void setOwner(Playable owner) {
this.owner = owner;
}
Абстрактные классы должны унаследоваться от, и когда один класс наследует от другого, это означает, что между двумя классами существует сильная связь. С другой стороны, с интерфейсом связь между самим интерфейсом и классом, реализующим интерфейс, не обязательно является сильной. Итак, мы можем обобщить этот первый пункт, сказав, что абстрактный класс будет более уместным, если будет существовать сильная связь между абстрактным классом и классами, которые будут получены из него. Опять же, это связано с тем, что абстрактный класс очень тесно связан с наследованием, что подразумевает сильные отношения. Но с интерфейсами не должно быть сильной связи между интерфейсом и классами, реализующими интерфейс. Интерфейс Java может расширять несколько интерфейсов, и Java-класс может реализовывать несколько интерфейсов, что означает, что интерфейс может обеспечить большую поддержку полиморфизма, чем абстрактный класс. Расширяя абстрактный класс, класс может участвовать только в одной иерархии типов, но с помощью интерфейса он может быть частью иерархии нескольких типов.
Чтобы реализовать интерфейс в Java, пока ваш класс не абстрактный, вам нужно для обеспечения реализации всех методов, что очень болезненно. С другой стороны, абстрактный класс может помочь вам в этом случае, предоставив реализацию по умолчанию.
Почти все, кажется, здесь уже рассмотрено. Добавление еще одного пункта в практическую реализацию класса abstract
:
blockquote>
abstract
также используется, чтобы исключить возможность класса инстанцирован. Если у вас есть конкретный класс, который вы не хотите создавать, сделайте егоabstract
.
Хм теперь люди голодные практический подход, вы совершенно правы, но большая часть интервьюера выглядит в соответствии с их текущим требованием и хочет практического подхода.
после завершения вашего ответа вы должны перейти на пример:
Аннотация:
, например, у нас есть функция зарплаты, которая имеет некоторый параметр, общий для всего сотрудника. то мы можем иметь абстрактный класс, называемый CTC, с частично определенным телом метода, и он будет расширяться всем типом сотрудника и получить редизайн в соответствии с их дополнительными значениями. Для общей функциональности.
public abstract class CTC {
public int salary(int hra, int da, int extra)
{
int total;
total = hra+da+extra;
//incentive for specific performing employee
//total = hra+da+extra+incentive;
return total;
}
}
class Manger extends CTC
{
}
class CEO extends CTC
{
}
class Developer extends CTC
{
}
Интерфейс интерфейса
в java позволяет иметь функциональность interfcae, не расширяя ее, и вы должны быть понятны с реализацией подписи функциональности, которую вы хотите ввести в ваше приложение. это заставит вас определиться. Для разных функций. публичный интерфейс EmployeType {
public String typeOfEmployee();
}
class ContarctOne implements EmployeType
{
@Override
public String typeOfEmployee() {
return "contract";
}
}
class PermanentOne implements EmployeType
{
@Override
public String typeOfEmployee() {
return "permanent";
}
}
, вы можете иметь такую вынужденную активность с абстрактным классом также с помощью определенных методов как абстрактного, теперь класс tha расширяет абстрактную абстрактную абстрактную абстрактную до тех пор, пока она не переопределит эту абстрактную функцию.
Я попытаюсь ответить, используя практический сценарий, чтобы показать различие между ними.
Интерфейсы имеют нулевую полезную нагрузку, т. е. никакое состояние не должно поддерживаться и, следовательно, лучше выбирать только ассоциировать контракт (возможность ) с классом.
Например, скажем, у меня есть класс Task, который выполняет какое-то действие, теперь для выполнения задачи в отдельном потоке мне действительно не нужно расширять класс Thread, а лучше выбирать Задача реализует интерфейс Runnable (т. Е. Реализует его метод run ()), а затем передает объект этого класса Task в экземпляр Thread и вызывает его метод start ().
Теперь вы можете спросить, что, если Runnable был абстрактным классом?
blockquote>Ну, технически это было возможно, но дизайн был мудрым, что было бы плохой причиной выбора:
- Runnable не имеет состояния, связанного с он и ни один из них не предлагает никакой реализации по умолчанию для метода run ()
- Задача должна была расширять ее, поэтому она не могла бы расширять любые другие c lass
- Задача не может быть предложена как специализация класса Runnable, все, что ей нужно, это переопределить метод run ()
. Другими словами, классу Task необходимо было быть запущен в потоке, который он достиг, реализуя стили интерфейса Runnable, расширяющие класс Thread, которые сделают его потоком.
Просто добавьте нам интерфейс для определения возможности (контракта), а используйте абстрактный класс для определения скелета (общей / частичной) реализации.
blockquote>Отказ от ответственности: глупый пример следует, постарайтесь не судить :-P
interface Forgiver { void forgive(); } abstract class GodLike implements Forgiver { abstract void forget(); final void forgive() { forget(); } }
Теперь у вас есть был выбран выбор, чтобы быть GodLike, но вы можете выбрать только Forgiver (т.е. а не GodLike) и do:
class HumanLike implements Forgiver { void forgive() { // forgive but remember } }
Или вы можете выбрать, чтобы быть GodLike и делать:
class AngelLike extends GodLike { void forget() { // forget to forgive } }
P.S. с интерфейсом java 8 также могут иметь статические, а также методы по умолчанию (переопределяемые реализации), и, таким образом, интерфейс b / w с разницей и абстрактный класс еще более сужаются.
В этом мире нет ничего прекрасного. Возможно, они ожидали большего практического подхода.
Но после вашего объяснения вы могли бы добавить эти строки несколько иначе.
Редактирование: Java 8 облегчает определение стандартных и статических методов в интерфейсе.
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
Теперь, когда класс будет реализовывать SomeInterface, необязательно предоставлять реализацию для по умолчанию методы интерфейса.
Если у нас есть другой интерфейс со следующими методами:
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Java не позволяет расширять несколько классов, потому что это приводит к задаче «Diamond», где компилятор не может решить, какой метод суперкласса использовать. С помощью методов по умолчанию проблема с алмазами будет возникать и для интерфейсов. Потому что, если класс реализует как
SomeInterfaceOne and SomeInterfaceTwo
, так и не реализует общий метод по умолчанию, компилятор не может решить, какой из них выбрать. Чтобы избежать этой проблемы, в java 8 обязательно применять общие методы по умолчанию для разных интерфейсов. Если какой-либо класс реализует оба вышеуказанных интерфейса, он должен обеспечить реализацию метода defaultMethod (), иначе компилятор будет вызывать ошибку времени компиляции.
Основное отличие, которое я наблюдал, это то, что абстрактный класс предоставляет нам некоторое обычное поведение, уже реализованное, и подклассы должны только реализовать определенные функциональные возможности, соответствующие им. где, как и для интерфейса, будет указываться только то, какие задачи необходимо выполнить, и никакие реализации не будут предоставлены интерфейсом. Я могу сказать, что он определяет контракт между собой и реализованными классами.
Интерфейс подобен набору генов, которые публично документированы, чтобы иметь какой-то эффект: тест на ДНК скажет мне, есть ли у меня их, и если да, я могу публично сообщить, что я «перевозчик» и часть моего поведения или состояния будут соответствовать им. (Но, конечно, у меня может быть много других генов, которые обеспечивают черты вне этой области.)
Абстрактный класс похож на мертвого предка однополого вида (*) : Она не может быть воплощена в жизнь, но живой (то есть не абстрактный ) наследник наследует все ее гены.
(*) Чтобы растянуть эту метафору, допустим, все члены видов живут до одного возраста. Это означает, что все предки мертвого предка тоже должны быть мертвы, а также все потомки живого предка должны быть живы.
Когда я пытаюсь разделить поведение между двумя тесно связанными классами, я создаю абстрактный класс, который содержит общее поведение и служит родителем для обоих классов.
Когда я пытаюсь определить тип , список методов, которые пользователь моего объекта может надежно вызвать, затем я создаю интерфейс.
Например, я бы никогда не создал абстрактный класс с 1 конкретным подклассом, потому что абстрактные классы касаются поведения совместного использования. Но я вполне мог бы создать интерфейс только с одной реализацией. Пользователь моего кода не будет знать, что существует только одна реализация. Действительно, в будущей версии может быть несколько реализаций, все из которых являются подклассами какого-то нового абстрактного класса, который даже не существовал, когда я создал интерфейс.
Это могло показаться слишком слишком книжным (хотя я никогда не видел, чтобы это было так, как я помню). Если бы интервьюер (или ОП) действительно хотел больше моего личного опыта по этому поводу, я был бы готов с анекдотами интерфейса, которые развивались по необходимости и наоборот.
Еще одна вещь. Теперь Java 8 позволяет поместить код по умолчанию в интерфейс, еще больше размывая границу между интерфейсами и абстрактными классами. Но из того, что я видел, эта функция слишком часто используется разработчиками ядровых библиотек Java. Эта функция была добавлена, и это правильно, чтобы было возможно расширить интерфейс без создания двоичной несовместимости. Но если вы создаете новый тип, определяя интерфейс, тогда интерфейс должен быть просто интерфейсом. Если вы хотите также предоставить общий код, то обязательно создайте вспомогательный класс (абстрактный или конкретный). Не запутывайте свой интерфейс с самого начала с функциональностью, которую вы можете изменить.
Основное отличие, которое я наблюдал, это то, что абстрактный класс предоставляет нам некоторое обычное поведение, уже реализованное, и подклассы должны только реализовать определенные функциональные возможности, соответствующие им. где, как и для интерфейса, будет указываться только то, какие задачи необходимо выполнить, и никакие реализации не будут предоставлены интерфейсом. Я могу сказать, что он определяет контракт между собой и реализованными классами.
Ваш ответ в порядке, но я думаю, что он искал такой ответ:
Абстрактный класс
Интерфейс
Вы выбираете интерфейс на Java, чтобы избежать проблемы с алмазом при множественном наследовании .
Если вы хотите, чтобы все ваши методы были реализованы вашим клиентом, вы идете на интерфейс. Это означает, что вы разрабатываете приложение в абстрактном виде.
Вы выбираете абстрактный класс, если уже знаете, что общего. Например, возьмите абстрактный класс Car
. На более высоком уровне вы реализуете общие автомобильные методы, такие как calculateRPM()
. Это обычный метод, и вы позволяете клиенту реализовать свое поведение, например calculateMaxSpeed()
и т. Д. Вероятно, вы бы объяснили, указав несколько примеров в реальном времени, с которыми вы столкнулись в повседневной работе.
Интерфейс является чисто абстрактным. у нас нет кода реализации в интерфейсе.
Абстрактный класс содержит оба метода и его реализацию.
Нажмите здесь, чтобы посмотреть учебник по интерфейсам и абстрактным классам
Ваше объяснение выглядит приличным, но может быть, похоже, что вы читали все это из учебника? : - /
Что мне больше беспокоит, насколько тверд был ваш пример? Вы пытались включить почти все различия между абстрактными и интерфейсами?
Лично я бы предложил эту ссылку: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
для исчерпывающего списка различий ..
Надеюсь, это поможет вам и всем остальным читателям в их будущих интервью
Даже я столкнулся с одним и тем же вопросом в нескольких интервью и полагаю, что это делает ваше время несчастным, чтобы убедить интервьюера. Если мне присущи все ответы сверху, то мне нужно добавить еще один ключевой момент, чтобы сделать его более убедительным и использовать OO в лучшем случае
. Если вы не планируете какую-либо модификацию правил , для последующего подкласса в течение долгого будущего, перейдите для интерфейса, поскольку вы не сможете его модифицировать, и если вы это сделаете, вам нужно перейти на изменения во всех других подклассах, тогда как, если вы считаете, вы хотите повторно использовать функциональные возможности, установите некоторые правила, а также сделайте их открытыми для модификации , перейдите для абстрактного класса.
Подумайте, таким образом, вы использовали расходную услугу или предоставили какой-то код миру, и у вас есть шанс что-то изменить, предположите проверку безопасности. И если я являюсь потребителем кода и Однажды утром после обновления, я нахожу все прочитанные метки в своем Eclipse, все приложение отключено. Поэтому, чтобы предотвратить такие кошмары, используйте Abstract over Interfaces
Я думаю, что это может убедить интервьюера в некоторой степени ... Счастливые интервью впереди.
Я считаю, что интервьюер пытался понять, возможно, это разница между интерфейсом и реализацией.
Интерфейс - не интерфейс Java, а «интерфейс» в более общих терминах - с кодовым модулем это, в основном, контракт с клиентским кодом, который использует интерфейс.
Реализация модуля кода - это внутренний код, который заставляет модуль работать. Часто вы можете реализовать конкретный интерфейс более чем одним способом и даже изменить реализацию без кода клиента, даже будучи осведомленным об этом изменении.
Интерфейс Java должен использоваться только как интерфейс в вышеупомянутом родовом чтобы определить, как класс ведет себя в интересах клиентского кода, используя класс, без указания какой-либо реализации. Таким образом, интерфейс включает в себя сигнатуры методов - имена, типы возврата и списки аргументов - для методов, которые, как ожидается, будут вызываться клиентским кодом, и в принципе должны иметь много Javadoc для каждого метода, описывающего, что делает этот метод. Наиболее убедительной причиной использования интерфейса является планирование нескольких различных реализаций интерфейса, возможно, выбор реализации в зависимости от конфигурации развертывания.
. Аспектный класс Java, напротив, обеспечивает частичную реализацию класс, а не с основной целью указания интерфейса. Он должен использоваться, когда несколько классов совместно используют код, но когда ожидается, что подклассы также будут включены в реализацию. Это позволяет совместному коду появляться только в одном месте - абстрактном классе - при этом ясно, что части реализации не присутствуют в абстрактном классе и, как ожидается, будут предоставляться подклассами.
Абстрактные классы - это не чистая абстракция bcz ее коллекция конкретных (реализованных методов), а также нереализованные методы. Но интерфейсы - это чистая абстракция bcz, то есть только нереализованные методы не являются конкретными методами.
Почему абстрактные классы?
Почему интерфейсы?