На одном из собеседований меня попросили объяснить разницу между интерфейсом и абстрактным классом.
Вот мой ответ:
Методы интерфейса Java неявно абстрактны и не могут иметь реализаций. Абстрактный класс Java может иметь методы экземпляра, которые реализуют поведение по умолчанию.
Переменные, объявленные в интерфейсе Java, по умолчанию являются конечными. На сайте абстрактный класс может содержать нефинальные переменные.
Члены интерфейса Java по умолчанию являются общедоступными. Абстрактный класс Java класс может иметь обычные типы членов класса, такие как private, protected и т. д.
Java-интерфейс должен быть реализован с помощью ключевого слова "implements"; Java-абстрактный класс должен быть расширен с помощью ключевого слова "extends". Абстрактный класс Java должен быть расширен с помощью ключевого слова "extends".
Интерфейс может расширять только другой интерфейс Java, абстрактный класс может расширять другой Java-класс и реализовывать несколько Java-интерфейсов.
Класс Java может реализовать несколько интерфейсов, но может расширять только один абстрактный класс.
Однако интервьюер не был удовлетворен и сказал мне, что это описание представляет собой "книжные знания".
Он попросил меня дать более практический ответ, объяснив, когда я предпочту абстрактный класс интерфейсу, используя практические примеры.
Где я ошибся?
Я приведу вам пример первый:
public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}
Теперь предположим, что у вас есть 3 базы данных в вашем приложении. После каждого внедрения для этой базы данных должен определить выше 2 метода:
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() не зависит от базы данных, и это's одинаково для каждого класса? Тогда выше не будет хорошим подходом.
Вместо этого, рассмотреть этот подход:
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 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 не позволяет расширять несколько классов, потому что это приводит к "проблеме алмаза ", когда компилятор не может решить, какой метод суперкласса использовать. С методами по умолчанию проблема алмаза возникнет и для интерфейсов. Потому что если класс реализует оба
SomeInterfaceOne and SomeInterfaceTwo
и не реализует общий метод по умолчанию, компилятор не может решить, какой из них выбрать. Чтобы избежать этой проблемы, в java 8 стало обязательным реализовывать общие методы по умолчанию для разных интерфейсов. Если какой-либо класс реализует оба вышеуказанных интерфейса, он должен предоставить реализацию метода defaultMethod(), иначе компилятор выдаст ошибку времени компиляции.
Вы сделали хорошее резюме практические различия в использовании и реализации, но ничего не сказал о разнице в смысл.
В интерфейс - это описание поведения класса, реализующего будет. Реализация Class гарантирует, что она будет иметь эти методы, которые могут быть использованы на нем. Это в основном договор или обещание классе должен сделать.
В абстрактный класс является основой для различных подклассы, которые делятся поведения, которые не должны быть повторно создан. Подклассы должны завершить поведения и иметь возможность изменить предопределенный поведения (пока это не определено как "конечное" или "частный").
Вы найдете хорошие примеры в языке Java.пакет утиль, который включает в себя такие интерфейсы, как список
и абстрактные классы как AbstractList, который уже реализует интерфейс. В документации описывает AbstractList
следующим образом:
этот класс обеспечивает скелетную реализацию интерфейса list, чтобы минимизировать усилия, необходимые, чтобы реализовать этот интерфейс поддерживается и "оперативной" и хранилище данных (например, массив).
Интерфейс состоит из одноэлементных переменных (общедоступные статические Заключительные) и публичных абстрактные методы. Мы обычно предпочитают использовать интерфейс в режиме реального времени, когда мы знаем, что делать, но Дон'т знаю, как это сделать.
Эту концепцию можно лучше понять на примере:
Рассмотрим платежную класс. Оплата может быть произведена множеством способов, таких как PayPal, кредитные карты и т. д. Поэтому мы обычно берем оплату как наш интерфейс, который содержит `makePayment (способ) и с помощью кредитной карты и PayPal являются два класса реализации.
public interface Payment
{
void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
public void makePayment()
{
//some logic for PayPal payment
//e.g. Paypal uses username and password for payment
}
}
public class CreditCard implements Payment
{
public void makePayment()
{
//some logic for CreditCard payment
//e.g. CreditCard uses card number, date of expiry etc...
}
}
В приведенном выше примере кредитной карты и PayPal являются два класса реализации /стратегии. Интерфейс также позволяет нам понятие множественного наследования в Java, который не может быть достигнуто путем абстрактного класса.
Мы выбираем абстрактный класс, когда есть некоторые особенности, для которых мы знаем, что делать, и другие особенности, которые мы знаем, как выполнить.
Рассмотрим следующий пример:
public abstract class Burger
{
public void packing()
{
//some logic for packing a burger
}
public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
public void price()
{
//set price for a veg burger.
}
}
public class NonVegBerger extends Burger
{
public void price()
{
//set price for a non-veg burger.
}
}
Если мы добавим методами (конкретная/абстрактная) в будущем для данного абстрактного класса, то класс реализации не нужно менять свой код. Однако, если мы добавим методов в интерфейсе, в будущем, мы должны добавить реализаций всех классов, которые реализовали этот интерфейс, в противном случае ошибки времени компиляции происходит.
Есть и другие отличия, но это основные из них, которые могут быть то, что ваш интервьюер ожидал . Надеюсь, это было полезно.
в Java 8 изменения в интерфейсе включают статические методы и методы по умолчанию интерфейсы. До Java 8, мы могли только объявления методов в интерфейсы. Но из Java 8, мы можем иметь методы по умолчанию и статические методы в интерфейсах.
после внедрения метода по умолчанию, кажется, что интерфейсы и абстрактные классы одинаковы. Тем не менее, они все-таки разные понятия в Java 8.
абстрактный класс может определять конструктор. Они более структурированы и может иметь состояние, связанное с ними. А напротив, по умолчанию способ может быть реализован только в условиях применения других методы интерфейса, без привязки к конкретной реализации'ы У государства. Таким образом, использование для разных целей и выбор между двумя действительно зависит от контекста сценария. Концептуальное Различие:
Абстрактные классы действительны для скелета (т. е. частичной) реализации интерфейсов, но не должен существовать без соответствующего интерфейса. Поэтому, когда абстрактные классы низводится до такой низкой видимости, реализации скелетной интерфейсов, может методов по умолчанию принять это как далеко? Решительно: Нет! Реализации интерфейсов почти всегда требует некоторых или всех из этих классов-строительные инструменты, какие методы по умолчанию не хватает. И если какой-то интерфейс не, это явно особый случай, который не должен ввести вас в заблуждение. Методы по умолчанию интерфейс в Java 8
В Java 8 представляет “методпо умолчанию” или (защитника методы) новая функция, которая позволяет разработчику добавлять новые методы в интерфейсах, не нарушая существующие реализации этих интерфейсов. Это обеспечивает гибкость, позволяющую определить интерфейс реализации, которые будут использоваться по умолчанию в случае, если класс бетона не обеспечивает реализацию этого метода. Давайте рассмотрим небольшой пример, чтобы понять, как это работает:
public interface OldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
+ " is added in interface");
}
}
Следующий класс будет успешно компилироваться в Java с JDK 8,
public class OldInterfaceImpl implements OldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
Если вы создаете экземпляр OldInterfaceImpl:
OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
методы по умолчанию являются не окончательными, могут быть не синхронизированы и не могут методы переопределения объекта. Они всегда являются открытыми, что серьезно ограничивает возможность писать короткие и многоразовые методов. Методы по умолчанию может быть предоставлен интерфейс, не затрагивая реализации классов как она включает в себя реализацию. Если каждый добавленный метод в интерфейс, определенный с реализации, то пострадавших нет класса реализации. Класс реализации может переопределить реализацию по умолчанию интерфейс. методы по умолчанию включить чтобы добавить новую функциональность к существующим интерфейсам не нарушая старых реализации этих интерфейсов. Когда мы расширяем интерфейс, который содержит метод по умолчанию, мы можем выполнить следующее
- Не переопределить метод по умолчанию и будет наследовать метод по умолчанию.
- Переопределить метод по умолчанию похож на другие методы мы переопределить в подкласс.
Переопределить метод по умолчанию как абстрактные, которые заставляют подкласса переопределить его.
Метод ошибка компиляции по каждому элементу решена, используя метод по умолчанию
Для Java 8, коллекций JDK было продлено и метод forEach добавляется ко всей коллекции (которые работают во взаимодействии с лямбдами). С обычным способом, код выглядит, как показано ниже,
public interface Iterable<T> {
public void forEach(Consumer<? super T> consumer);
}
Поскольку этот результат каждый класс реализует С поэтому ошибки компиляции, метод по умолчанию добавляется обязательное выполнение для того, что существующие реализации не должны быть изменены. Интерфейс Iterable с методом по умолчанию ниже,
public interface Iterable<T> {
public default void forEach(Consumer
<? super T> consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
Поскольку Java-класс может реализовывать несколько интерфейсов, и каждый интерфейс может определить методом по умолчанию с одинаковой сигнатурой метода, следовательно, наследуемые методы могут конфликтовать друг с другом. Рассмотрим ниже пример,
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
Приведенный выше код не будет компилироваться из-за ошибки,
Java: класс осущ наследует несвязанные значения по умолчанию для defaultMethod() от типы InterfaceA и InterfaceB Для того, чтобы исправить этот класс, нам нужно обеспечить способ реализация по умолчанию:
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
}
}
Далее, если мы хотим, чтобы вызвать реализацию по умолчанию, предоставляемые любой из супер интерфейс, а не наши собственные реализации, мы можем сделать это следующим образом,
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
Статический метод Java-интерфейс, пример кода, статический метод против метода по умолчанию Статический метод Java-интерфейс похож на метод по умолчанию, за исключением того, что мы не можем их переопределить в классах реализации. Эта функция помогает нам избежать нежелательных результатов при плохой реализации в классы реализации. Давайте рассмотрим это на простом примере.
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
Теперь давайте посмотрим класса реализации, который имеет функцию isnull() метод, с плохой реализацией.
public class MyDataImpl implements MyData {
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
Обратите внимание, что функция isnull ул.(строка) представляет собой простой метод класса, это не переопределение метода интерфейса. Например, если мы добавим аннотацию @override в функции isnull() метод, это приведет к ошибке компилятора. Теперь, когда мы запустим приложение, мы получаем следующий результат.
интерфейс значение null проверить
осущ значение null проверить Если мы делаем интерфейс метода из статического по умолчанию, мы получим следующий вывод. осущ значение null проверить
Мои_данные печати::
осущ значение null проверить Статический метод Java-интерфейс видна только методы интерфейса, если мы уберем функцию isnull() метод из класса MyDataImpl, мы не сможем использовать его для объекта MyDataImpl. Однако, как и другие статические методы, мы можем использовать статические методы интерфейса, используя имя класса. Например, действительное заявление будет:
boolean result = MyData.isNull("abc");
@FunctionalInterface
был введен, чтобы отметить интерфейс, как функциональный интерфейс. Аннотации @FunctionalInterface
является средством, чтобы избежать случайного сложения абстрактных методов в функциональных интерфейсов. Это необязательно, но хорошая практика, чтобы использовать его.
Функциональные интерфейсы долгожданным и желанным особенность Явы 8, т. к. это дает возможность использовать лямбда-выражения, чтобы инстанцировать их. Новый пакет Java.утиль.функция с кучей функциональных интерфейсов для целевых типов для лямбда-выражения и ссылки на методы. Мы рассмотрим функциональные интерфейсы и лямбда-выражения в будущих постах.
Расположение Ресурса: Все ваши заявления остаются в силе, а ваше первое заявление (после релиза Java 8):
методы Java-интерфейс неявно являются абстрактными и не имеют реализации
Из документации Страница:
интерфейс является ссылочным типом, похожие на класс, который может содержать только константы сигнатуры методов, методы по умолчанию, статические методы и вложенные типы
существует способ тела только для методов и статических методов.
Методы по умолчанию:
Интерфейс может иметь методы по умолчанию, но несколько иначе, чем абстрактные методы в абстрактных классах.
стандартные методы позволят вам добавить новые функциональные возможности, интерфейсы библиотек и обеспечения бинарной совместимости с кодом, написанным для предыдущих версий этих интерфейсов.
При расширении интерфейс, который содержит метод по умолчанию, вы можете сделать следующее:
Статические Методы:
Помимо методов по умолчанию, вы можете определить статические методы в интерфейсах. (Статический метод это метод, связанный с классом, в котором он определен, а не с каким-либо объектом. Каждый экземпляр класса разделяет его статические методы.)
Это делает его легче для вас, чтобы организовать вспомогательные методы в библиотеках;
Пример кода со страницы документации о интерфейс
иметь статические
методы и по умолчанию
.
import java.time.*;
public interface TimeClient {
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
int hour, int minute, int second);
LocalDateTime getLocalDateTime();
static ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
Используйте руководство ниже, чтобы выбрать, следует ли использовать интерфейс или абстрактный класс.
Интерфейс:
Абстрактный класс:
Поделиться код между несколькими тесно связанных классов. Он устанавливает является отношения.
Доля общего государства между классы ( государство может быть изменен в конкретные классы)
Похожие сообщения:
https://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo/33963650#33963650
Пройдя через эти примеры, можно понять, что
Несвязанные классы могут иметь функции через интерфейс, но взаимосвязанных классов изменение поведения посредством расширения базовых классов.
Ваше объяснение выглядит достойно, но, возможно, это выглядит так, как будто вы читаете все это из учебника? :-/
Что меня больше беспокоит, так это то, насколько основательным был ваш пример? Потрудились ли вы включить почти все различия между абстракциями и интерфейсами?
Лично я бы посоветовал эту ссылку: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
где приведен исчерпывающий список различий.
Надеюсь, это поможет вам и всем остальным читателям в их будущих интервью.
Многие младшие разработчики делают ошибку, думая, интерфейсов, абстрактных и конкретных классов, как небольшими вариациями одно и то же, а выбрать один из них чисто по техническим причинам: нужно множественное наследование? Мне нужны какие-то место для общих методов? Нужно ли мне беспокоиться о чем-то другом, чем просто конкретный класс? Это неправильно, и скрытые в этих вопросах и заключается главная проблема: quot;Я" и;. Когда вы пишете код для себя, самостоятельно, вы редко думают о других настоящих или будущих разработчиков, работающих на или с вашим кодом. Интерфейсы и абстрактные классы, хотя внешне схожие с технической точки зрения, имеют совершенно разные смыслы и цели.
Иначе говоря: конкретного класса выполняет основную работу, в очень специфическим образом. Например, в коллекции
использует непрерывную область памяти для хранения списка объектов в компактной форме, которая обеспечивает быстрый произвольный доступ, итерации, и в месте изменения, но ужасно инсерции, делеции, а иногда даже и дополнениями; между тем, В класса LinkedList
использует двойную-связанных узлов для хранения списка объектов, который вместо этого предлагает быстрый итерации, в месте изменения и вставки/удаления/добавления, но страшно на произвольный доступ. Эти два вида списков оптимизированы для различных вариантов использования, и это имеет большое значение, как вы'ре собирается использовать их. Когда вы'вновь пытается выжать производительность из списка, что вы'вновь активно взаимодействуют с, и при выборе типа из списка, вы должны тщательно выбирать, что вы'повторного создания экземпляра.
С другой стороны, пользователям высокий уровень список Дон'т действительно волнует, как это осуществляется на деле, и они должны быть изолированы от этих подробностей. Позвольте'ы представляю, что Java не'т подвергайте список
интерфейс, но только класса бетона список
, что'ов на самом деле что LinkedList не является сейчас. Все Java-разработчиков с учетом их код, чтобы соответствовать детали реализации: во избежание произвольного доступа, добавьте кэш для ускорения доступа, или просто переопределить коллекции
самостоятельно, хотя это было бы несовместимо с другими код, который на самом деле работает с "списком" только. Это было бы ужасно... но теперь представим, что инженеры на самом деле понимают, что это страшно для большинства реальных случаев использования, и решил переключиться на список массива только для своих список
класса. Это будет влиять на производительность каждый Java-программа в мире, и люди не'т быть счастливым об этом. И главным виновником является то, что детали реализации были доступны, и разработчики предполагали, что эти детали являются постоянный контракт, который они могут положиться. Это почему это's важный, чтобы скрыть детали реализации, и определять только абстрактный договор. Именно с этой целью и интерфейса: определить, какие данные метод можно, и какие результаты ожидать, не подвергая всеми потрохами, что бы искушать программистов, чтобы подправить свой код, чтобы соответствовать внутренние детали, которые могут меняться с обновлениями.
Абстрактный класс-это посередине между интерфейсы и классы бетона. Это должно помочь реализации общие и скучный код. Например, AbstractCollection
предоставляет базовую реализацию для пустой
на основе размер 0, содержит
, как перебирать и сравнивать, добавим
повторяющихся добавить
, и так далее. Это позволяет сосредоточиться на реализации наиболее важных частей, что различие между ними: как на самом деле хранить и извлекать данные.
Интерфейсы низким уровнем сплоченности шлюзов между различными частями кода. Они позволяют библиотекам существовать и развиваться, не нарушая каждый пользователь библиотеки, когда что-то внутри изменяется. Это's посетило прикладное программирование интерфейс, не классы прикладного программирования. В меньших масштабах, кроме того, они позволяют нескольким разработчикам успешно сотрудничают в масштабных проектах, разделяя различные модули через хорошо документированные интерфейсы. Абстрактные классы являются высокая сплоченность помошников для использования при реализации интерфейса, предполагая определенный уровень реализации. Кроме того, абстрактные классы используются для определения Спиш, интерфейсы поставщика услуг. Разница между собой API и SPI очень тонкое, но важное: для API, фокус находится на используется он, и спи фокус находится на осуществляет он. Добавление методов в API легко, все существующие пользователи API будет по-прежнему компилироваться. Добавление методов к Сио сложно, так как каждый поставщик услуг (конкретная реализация) придется внедрять новые методы. Если интерфейсы используются для определения спи, поставщику придется выпустить новую версию, когда договор спи изменения. Если абстрактные классы используются вместо этого, новые методы быть определены в терминах существующих абстрактных методов, или как "пустые" выбросить не реализовано заглушки исключения, которые по крайней мере позволяют более старую версию реализации сервиса все-таки скомпилировать и запустить.
Хотя в Java 8 введен методов по умолчанию для интерфейса, который делает грань между интерфейсами и абстрактными классами, даже размытым, это было'т так что реализации могут повторно использовать код, но чтобы сделать его проще поменять интерфейсы, которые могут использоваться как в качестве API и как с SPI (или неправильно используемые для определения Спиш вместо абстрактных классов).
Технические данные, указанные в ОП'ответом считается-то "Книга знаний" - А ведь обычно это подход, используемый в школе и в большинстве технических книг о языке: что вещь, а не как чтобы использовать это на практике, особенно в крупномасштабных приложений. Здесь'ы аналогию: предполагаемый вопрос:
что лучше сдать в аренду на выпускной вечер, автомобиль или номер в отеле? Технический ответ звучит так: Ну, в машине, вы можете сделать это раньше, но в гостиничном номере, вы можете сделать это более комфортно. С другой стороны, отель находится только в одном месте, в то время как в автомобиле вы можете делать это в нескольких местах, мол, давайте'говорят, что вы можете перейти на Висте точки для приятного просмотра, или в театр, или многих других местах, или даже в более чем одном месте. Кроме того, в номере есть душ. Это все верно, но совершенно не попадает в очки, что это две совершенно разные вещи, и оба можно использовать одновременно для разных целей, и "делает ее" аспект-это не самое главное в любом из этих двух вариантов. Ответ нет точки зрения, он показывает незрелого мышления, в то время как правильно представляя правда, что "Факты" по.
Интерфейс - это "контракт", в котором класс, реализующий контракт, обещает реализовать методы. Примером того, как мне пришлось писать интерфейс вместо класса, может служить обновление игры из 2D в 3D. Мне нужно было создать интерфейс для обмена классами между 2D и 3D версиями игры.
package adventure;
import java.awt.*;
public interface Playable {
public void playSound(String s);
public Image loadPicture(String s);
}
Тогда я могу реализовать методы, основанные на окружении, и при этом иметь возможность вызывать эти методы из объекта, который не знает, какая версия игры загружается.
Публичный класс 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;
}
Насчет мышления следующим образом:
Поэтому, когда у вас есть абстрактный класс млекопитающие, подкласс человека, и интерфейс управлять, тогда вы можете сказать
Мое предложение заключается в том, что разговорник знания указывает на то, что он хотел услышать смысловая разница между ними (как и другие уже здесь предлагали).
Абстрактные классы не чистой абстракции BCZ его коллекция из бетона(реализованных методов), а также нереализованных методов. Но Интерфейсы являются чистой абстракцией, тут есть только нереализованные методы не конкретные методы.
Почему абстрактные классы?
Почему Интерфейсы?
Ан интерфейс - это как набор генов, которые публично задокументированы, чтобы иметь какой-то эффект: ДНК тест скажет мне, правильно ли я'ве получил их - и если я это сделаю, я могу публично дать понять, что я'м а "Перевозчик" и частью мое поведение или состояние будет соответствовать их. (Но, конечно, я, возможно, многих других генов, обеспечивающих черты характера за пределами этой области.)
В абстрактный класс это как мертвого предка однополых видов(): она может'т быть привлечены к жизни, но жизнь (т. е. неабстрактный*) потомок наследует все ее гены.
(*) Чтобы растянуть эту метафору, пусть'ы сказать, что все представители вида живут в том же возрасте. Это означает, что все предки умершего предка должны также быть мертвым - и кроме того, все потомки живого предка должен быть жив.
Вы выбрали интерфейс в Java, чтобы избежать проблема Алмаз множественное наследование.
Если вы хотите, чтобы все ваши методы должны быть осуществлены вашим клиентом вы идете на интерфейс. Это означает, что вы дизайн всего приложения в аннотация.
Вы выберете абстрактный класс, если вы уже знаете, что общего. Например взять машину абстрактный класс. На более высоком уровне реализации общих методов машину, как
calculateRPM(). Это распространенный метод и позволить клиенту выполнять свое собственное поведение, как
calculateMaxSpeed()` и т. д. Наверное, вы бы объяснили, дав несколько реального времени примеры, которые вы сталкиваетесь в вашей повседневной работе.
Я делаю интервью для работы, и я буду выглядеть неблагоприятно на ваш ответ хорошо (извините, но я очень честный). Это звучит, как вы'вэ прочитать о разнице и пересмотренный ответ, но возможно вы никогда не использовали его на практике.
Хорошее объяснение, почему вы бы использовать каждый может быть гораздо лучше, чем иметь точное объяснение разницы. Работодатели ultimatley хочу программистов, чтобы делать вещи, не знать которые может быть трудно продемонстрировать в интервью. Ответ вы дали бы хорошо, если претендуете на технической или документации на основании задания, но не в роли разработчиков.
Удачи с интервью в будущем.
Также мой ответ на этот вопрос является больше о технике интервью, а не технический материал вы предоставили. Возможно, читая об этом. https://workplace.stackexchange.com/ может стать отличным местом для такого рода вещи.
Интерфейс-это чисто абстрактное. мы не имеем никакого кода в интерфейс.
Абстрактный класс содержит оба метода и его реализации.
[нажать здесь, чтобы посмотреть учебник по интерфейсов и абстрактных классов][1]
Главное отличие, что я заметил, было то, что абстрактный класс предоставляет нам некоторые общие поведение уже реализовано и подклассы нужны только для реализации определенных функций, связанных с ними. где в качестве интерфейса будет только указать, какие задачи должно быть сделано, и нет реализаций будут даны интерфейс. Я могу сказать, что это определяет контракт между собой и выполнены классов.
Даже я столкнулась один и тот же вопрос в нескольких интервью, и поверьте, это делает ваше время несчастной, чтобы убедить интервьюера. Если мне присущи все ответы из вышеуказанной тогда мне нужно добавить еще один ключевой момент, чтобы сделать его более убедительным и использования ОО в лучшем виде
В случае, если вы не <б> планировать какие-либо изменения в правилах, </б> для подкласса, чтобы следовать, в далеком будущем, пойти на интерфейс, как вы не сможете изменить в нем, и если вы это сделаете, вам нужно перейти к изменениям во всех других подклассов, в то время как, если вы думаете, <б> вы хотите использовать функциональность, установить некоторые правила, а также сделать его открытым для модификации</б>, пойти на абстрактный класс.
Думаю, в этом случае, вы использовали расходные обслуживании или вы предоставили какой-то код в мире и у тебя есть шанс изменить что-то, предположим, что проверка безопасности И если я, будучи потребителем код и однажды утром, после обновления , я нашел все знаки прочитать в моей затмение, все приложения. Поэтому, чтобы предотвратить такие кошмары, применение абстрактных интерфейсов
Я думаю, это может убедить интервьюера в степени...счастлив впереди интервью.
Когда я пытаюсь поделиться поведении между 2 тесно связанных классов, я создаю абстрактный класс, который содержит общее поведение и выступает в качестве родителя для обоих классов.
Когда я пытаюсь определить тип, список методов, которые пользователь объекта может надежно призовут, то я создаю интерфейс.
Например, я бы никогда не создать абстрактный класс с 1 конкретный подкласс, потому что абстрактные классы о совместном поведении. Но я мог бы очень хорошо создать интерфейс с только одна реализация. Пользователь мой код выиграл'т знаем, что есть только одна реализация. Действительно, в будущих версиях их может быть несколько реализаций, которые являются подклассами какой-то новый абстрактный класс, который не'т даже существовать, когда я создал интерфейс.
Это может показаться немного слишком по-книжному (хотя я никогда не видел его так нигде, что я помню). Если интервьюер (или ОП) на самом деле хотел, больше из моего личного опыта, я был бы готов с анекдотами интерфейса превратилась из необходимости, и наоборот.
Еще одна вещь. В Java 8 теперь позволяет поставить код по умолчанию в интерфейсе, дальнейшее размывание грань между интерфейсами и абстрактными классами. Но от того, что я видел, эта функция злоупотреблять даже создателей ядром Java библиотеки. Эта функция была добавлена, и это правильно, чтобы сделать его возможным для расширения интерфейса, не создавая бинарную несовместимость. Но если вы делаете новый тип с определения интерфейса, то интерфейс должен быть только интерфейс. Если вы хотите также обеспечить общий код, то все средства сделать вспомогательный класс (абстрактный или конкретный). Дон'т быть загромождая интерфейс с функциональностью, что можно изменить.
Принципиальная разница между интерфейсом и абстрактным классом, интерфейс поддерживает множественное наследование, но не абстрактный класс.
В абстрактном классе также можно предоставить все абстрактные методы, такие как интерфейс.
зачем нужен абстрактный класс?
В некоторых случаях, при обработке запроса пользователя, абстрактный класс не'т знаю, что намерения пользователя. В этом случае мы определим один абстрактный метод в классе и попросите пользователя, чтобы расширить этот класс, пожалуйста, представьте ваше намерение в абстрактный метод. В этом случае абстрактные классы очень полезны
Зачем нужен интерфейс?
Позвольте'ы сказать, у меня есть работа, которую я Дон't есть опыт в этой области. Например, если вы хотите построить дом или плотину, то что вы будете делать в этом случае?
Здесь я Дон'т беспокоиться о логике, как они построены. Окончательный объект удовлетворены мои требования или нет, это только мой ключевой момент.
Здесь вашим требованиям называемый интерфейс и строители называют конструктором.
В абстрактном классе можно оставить по умолчанию реализация методов! Но в интерфейсе вы не можете. В основном, в интерфейсе существуют чисто виртуальные методы, которые должны быть реализованы в классе, который реализует интерфейс.