Абстрактный класс против интерфейса в Java

Мне задали вопрос, я хотел, чтобы мой ответ был рассмотрен здесь.

Q: В каком сценарии более целесообразно расширять абстрактный класс, а не реализовывать интерфейс (ы)?

A: Если мы используем шаблон шаблона дизайна шаблона.

Я прав ?

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

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

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

3) мы можем расширить максимум одного абстрактного класса, но можем реализовать более одного интерфейса

Reiterating the question: Существуют ли какие-либо другие сценарии, помимо упомянутых выше, где нам конкретно требуется использовать абстрактный класс (можно увидеть, что шаблонный шаблонный метод концептуально основан только на этом)?

Интерфейс против абстрактного класса

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

Как всегда есть компромисс, интерфейс дает вам свободу в отношении базового класса, абстрактный класс дает вамfreedom to add new methods later, & # X2013; Эрих Гамма

Выcan’t go and change an Interface without having to change a lot of other things в вашем коде, поэтому единственный способ избежать этого - создать совершенно новый интерфейс, что не всегда может быть полезным.

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

 Shiplu Mokaddim06 апр. 2012 г., 08:55
Это не дубликат. ОП хочет знать, когдаextend абстрактный класс, а не реализовать интерфейс. Он не хочет знать, когда писать абстрактный класс или интерфейс. Его абстрактный класс и интерфейс уже написаны. Hd хочет знать, расширять или внедрять.
 bezmax06 апр. 2012 г., 08:44
возможный дубликатInterface vs Abstract Class (general OO)
 nawfal07 июл. 2014 г., 12:17
возможный дубликатWhen to use abstract class or interface?
 Sandeep Manne06 апр. 2012 г., 08:45
 user20742106 апр. 2012 г., 10:09
@ shiplu.mokadd.im Это различие без разницы. Вы не можете использовать абстрактный класс, не расширяя его. Ваш придирки здесь кажутся совершенно бессмысленными.

Ответы на вопрос(14)

Здесь много хороших ответов, но я часто нахожу использование ОБА интерфейсов, и абстрактные классы - лучший путь.Consider this contrived example:

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

1) Trading system places orders
2) Trading system receives acknowledgements

и может быть захвачен в интерфейсе,ITradeSystem

public interface ITradeSystem{

     public void placeOrder(IOrder order);
     public void ackOrder(IOrder order);

}

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

Итак, вы идете вперед и построить систему дляstock трейдеры; они слышали, что в вашей системе есть функция поиска дешевых акций, и очень хотят ее опробовать! Вы фиксируете это поведение в методеfindGoodDeals()но также понимают, что есть много грязных вещей, которые связаны с подключением к рынкам. Например, вы должны открытьSocketChannel,

public class StockTradeSystem implements ITradeSystem{    

    @Override 
    public void placeOrder(IOrder order);
         getMarket().place(order);

    @Override 
    public void ackOrder(IOrder order);
         System.out.println("Order received" + order);    

    private void connectToMarket();
       SocketChannel sock = Socket.open();
       sock.bind(marketAddress); 
       <LOTS MORE MESSY CODE>
    }

    public void findGoodDeals();
       deals = <apply magic wizardry>
       System.out.println("The best stocks to buy are: " + deals);
    }

Конкретные реализации будут иметь много таких грязных методов, какconnectToMarket(), ноfindGoodDeals() это все трейдеры на самом деле заботятся.

Now here's where abstract classes come into play.  Ваш босс сообщает вам, что валютные трейдеры также хотят использовать вашу систему. И, глядя на валютные рынки, вы видите, что сантехника почти идентична фондовым рынкам. По факту,connectToMarket() может быть повторно использован дословно для подключения к валютным рынкам. Тем не мение,findGoodDeals() это совершенно другая концепция на валютной арене. Поэтому, прежде чем передать кодовую базу ребёнку, работающему с иностранной валютой через океан, вы сначала сделаете рефакторинг вabstract класс, уходяfindGoodDeals() unimplmented

public abstract class ABCTradeSystem implements ITradeSystem{    

    public abstract void findGoodDeals();

    @Override 
    public void placeOrder(IOrder order);
         getMarket().place(order);

    @Override 
    public void ackOrder(IOrder order);
         System.out.println("Order received" + order);    

    private void connectToMarket();
       SocketChannel sock = Socket.open();
       sock.bind(marketAddress); 
       <LOTS MORE MESSY CODE>
    }

Ваша система торговли акциями реализуетfindGoodDeals() как вы уже определили,

public class StockTradeSystem extends ABCTradeSystem{    

    public void findGoodDeals();
       deals = <apply magic wizardry>
       System.out.println("The best stocks to buy are: " + deals);
    }

но теперь одаренный FX может построить свою систему, просто обеспечив реализациюfindGoodDeals() для валют; ей не нужно переопределять сокетные соединения или даже методы интерфейса!

public class CurrencyTradeSystem extends ABCTradeSystem{    

    public void findGoodDeals();
       ccys = <Genius stuff to find undervalued currencies>
       System.out.println("The best FX spot rates are: " + ccys);
    }

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

Note: можно задаться вопросом, почемуfindGreatDeals() не является частью интерфейса. Помните, что интерфейс определяет самые общие компоненты торговой системы. Другой инженер может разработать ПОЛНОСТЬЮ РАЗНУЮ торговую систему, в которой он не заботится о поиске хороших сделок. Интерфейс гарантирует, что отдел продаж также может взаимодействовать со своей системой, поэтому предпочтительно не связывать ваш интерфейс такими понятиями приложения, как «выгодные предложения».

За последние три года многое изменилось с добавлением новых возможностей для взаимодействия с выпуском Java 8.

Из оракульной документациистраница на интерфейсе:

An interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. Method bodies exist only for default methods and static methods.

Как вы указали в своем вопросе, абстрактный класс лучше всего подходит дляtemplate method pattern где вы должны создать скелет. Интерфейс не может быть использован здесь.

Еще одно соображение, чтобы предпочесть абстрактный класс интерфейсу:

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

Abstract class establishes "is a" relation between related classes and interface provides "has a" capability between unrelated classes.

Что касается второй части вашего вопроса, которая действительна для большинства языков программирования, включая Java доjava-8 релиз

As always there is a trade-off, an interface gives you freedom with regard to the base class, an abstract class gives you the freedom to add new methods later. – Erich Gamma

You can’t go and change an Interface without having to change a lot of other things in your code

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

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.

Чтобы выбрать один из них между интерфейсом и абстрактным классом, документация оракуластраница процитирую это:

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods.

With interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public. In addition, you can extend only one class, whether or not it is abstract, whereas you can implement any number of interfaces.

Обратитесь к этим связанным вопросам для более подробной информации:

Интерфейс против абстрактного класса (общий ОО)

Как мне объяснить разницу между интерфейсом и абстрактным классом?

В итоге :The balance is tilting more towards interfaces now.

Are there any other scenarios, besides those mentioned above, where specifically we require to use abstract class (one is see is template method design pattern is conceptually based on this only)?

Некоторые шаблоны проектирования используют абстрактные классы (поверх интерфейсов) отдельно от шаблона метода Template.

Creational patterns:

Abstract_factory_pattern

Structural patterns:

Decorator_pattern

Behavioral patterns:

Mediator_pattern

 01 февр. 2019 г., 08:59
Это: "Абстрактный класс устанавливает" является " связь между связанными классами и интерфейсом обеспечивает "имеет" возможность между несвязанными классами. & quot;

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

Это мое понимание, надеюсь, это поможет

Abstract classes:

Can have member variables that are inherited (can’t be done in interfaces) Can have constructors (interfaces can’t) Its methods can have any visibility (ie: private, protected, etc - whereas all interface methods are public) Can have defined methods (methods with an implementation)

Interfaces:

Can have variables, but they are all public static final variables constant values that never change with a static scope non static variables require an instance, and you can’t instantiate an interface All methods are abstract (no code in abstract methods) all code has to be actually written in the class that implements the particular interface

reiterating the question: there is any other scenario besides these mentioned above where specifically we require to use abstract class (one is see is template method design pattern is conceptually based on this only)

Да, если вы используете JAXB. Не любит интерфейсы. Вам следует либо использовать абстрактные классы, либо обойти это ограничение с помощью обобщений.

Из личного блогасообщение:

Interface:

A class can implement multiple interfaces An interface cannot provide any code at all An interface can only define public static final constants An interface cannot define instance variables Adding a new method has ripple effects on implementing classes (design maintenance) JAXB cannot deal with interfaces An interface cannot extends or implement an abstract class All interface methods are public

In general, interfaces should be used to define contracts (what is to be achieved, not how to achieve it).

Abstract Class:

A class can extend at most one abstract class An abstract class can contain code An abstract class can define both static and instance constants (final) An abstract class can define instance variables Modification of existing abstract class code has ripple effects on extending classes (implementation maintenance) Adding a new method to an abstract class has no ripple effect on extending classes An abstract class can implement an interface Abstract classes can implement private and protected methods

Abstract classes should be used for (partial) implementation. They can be a mean to restrain the way API contracts should be implemented.

 25 сент. 2018 г., 17:32
В Java 8 для интерфейса # 8 вы можете иметьdefault а такжеstatic методы тоже.

Абстрактные классы отличаются от интерфейсов в двух важных аспектах

they provide default implementation for chosen methods (that is covered by your answer) abstract classes can have state (instance variables) - so this is one more situation you want to use them in place of interfaces
 09 янв. 2016 г., 12:01
Я хотел бы завершить, что интерфейсы могут иметь переменные, но они по умолчанию являются окончательными.

Что вы должны использовать, абстрактные классы или интерфейсы?

Consider using abstract classes if any of these statements apply to your scenario:

Вы хотите поделиться кодом между несколькими тесно связанными классами.

Вы ожидаете, что классы, которые расширяют ваш абстрактный класс, имеют много общих методов или полей или требуют модификаторов доступа, отличных от public (например, protected и private).

Вы хотите объявить нестатические или не финальные поля. Это позволяет вам определять методы, которые могут обращаться и изменять состояние объекта, к которому они принадлежат.

Consider using interfaces if any of these statements apply to your situation:

Вы ожидаете, что несвязанные классы будут реализовывать ваш интерфейс. Например, интерфейсы Comparable и Cloneable реализованы многими несвязанными классами.

Вы хотите указать поведение определенного типа данных, но не беспокоитесь о том, кто реализует его поведение.

Вы хотите воспользоваться множественным наследованием типа.

http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

На мой взгляд, основное отличие заключается в том, чтоan interface can't contain non abstract methods while an abstract class can. So if subclasses share a common behaviour, this behaviour can be implemented in the super class and thus inherited in the subclasses

Также я процитировал следующее из статьи «ppatterns проектирования архитектуры программного обеспечения в Java». книга

& Quot; В языке программирования Java нет поддержки множественного наследования. Это означает, что класс может наследовать только от одного отдельного класса. Отсюда и наследство следует использовать только тогда, когда это абсолютно необходимо. По возможности, методы обозначающее общее поведение должно быть объявлено в форме интерфейса Java быть реализованным различными классами реализатора. Но интерфейсы страдают от ограничение в том, что они не могут обеспечить реализацию методов. Это означает, что каждый разработчик интерфейса должен явно реализовывать все объявленные методы в интерфейсе, даже если некоторые из этих методов представляют собой неизменную часть функциональности и имеют одинаковую реализацию во всех классах реализатора. Это приводит к избыточному коду. Следующий пример демонстрирует как шаблон Abstract Parent Class может использоваться в таких случаях без требующие реализации избыточных методов. & quot;

When To Use Interfaces

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

When To Use Abstract classes

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

When to Use Both

Вы можете предложить лучшее из обоих миров, интерфейс и абстрактный класс. Реализаторы могут игнорировать ваш абстрактный класс, если захотят. Единственный недостаток - вызов методов через имя их интерфейса немного медленнее, чем вызов через абстрактное имя класса.

 06 апр. 2012 г., 08:52
Я думаю, что ОП хочет знать, когдаextend абстрактный класс, а не реализовать интерфейс
 06 апр. 2012 г., 09:53
@ shiplu.mokadd.im Я не вижу, как это дает вам право неправильно формулировать его вопрос.
 06 апр. 2012 г., 10:02
Только на основании этого единственного заявленияIf we are using template method design pattern Мы не можем сказатьYES или жеNO
 06 апр. 2012 г., 09:10
Ты прав. Но в SO мы отвечаем да / нет с надлежащим объяснением.
 06 апр. 2012 г., 08:54
@ shiplu.mokadd.im На самом деле ФП задал очень конкретный вопрос, на который можно ответить либо «да»; или "нет".

Вы не правы. Есть много сценариев. Просто невозможно свести его к одному правилу из 8 слов.

 06 апр. 2012 г., 10:34
Если вы не смутны, как; Используйте интерфейс всякий раз, когда вы можете;)
 06 апр. 2012 г., 12:17
Это «переполнение стека» в конце концов. ;) Я хочу сказать, что если вы можете использовать более простой интерфейс, сделайте это. В противном случае у вас нет выбора, кроме как использовать абстрактный класс. Я не считаю это очень сложным.
 10 апр. 2014 г., 14:06
Я думаю, вы могли бы дать более конструктивную идею. нравится говорить о некоторых репрезентативных сценариях /
 06 апр. 2012 г., 11:48
@PeterLawrey Да, не позволяйте круговым спорам замедлять вас ;-)

Самый короткий ответ:extend абстрактный класс, когда некоторые из функций, которые вы ищете, уже реализованы в нем.

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

Вшаблон дизайна шаблона должно быть определено поведение. Это поведение зависит от других методов, которые являются абстрактными. Делая подкласс и определяя эти методы, вы фактически определяете основное поведение. Базовое поведение не может быть в интерфейсе, так как интерфейс ничего не определяет, он просто объявляет. Таким образом, шаблон дизайна шаблона всегда поставляется с абстрактным классом. Если вы хотите сохранить поток поведения без изменений, вы должны расширить абстрактный класс, но не переопределять основное поведение.

 08 дек. 2015 г., 11:35
Дополнительная ссылка дляPure Virtual Function добавит больше идей оConvergence of Abstract Class & Interface, Pure virtual functions can also be used where the method declarations are being used to define an interface - similar to what the interface keyword in Java explicitly specifies. In such a use, derived classes will supply all implementations. In such a design pattern, the abstract class which serves as an interface will contain only pure virtual functions, but no data members or ordinary methods.   Часть (1/2)
 08 дек. 2015 г., 11:37
Часть (2/2)Divergence of Abstract Class & Interface объясняется последней строкой вышеno data members or ordinary methods[в абстрактном классе].

Abstract classes should be extended when you want to some common behavior to get extended, Абстрактный суперкласс будет иметь общее поведение и будет определять абстрактный метод / специфическое поведение, которое должны реализовывать подклассы.

Interfaces allows you to change the implementati,on anytime allowing the interface to be intact.

Использование аннотации и интерфейса:

У каждого есть "Is-A-Relationship" и у другого есть «Имеет отношения».

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

Пример: - & gt; В людях у нас есть некоторые свойства по умолчанию: еда, сон и т. Д., Но если у кого-то есть какие-либо другие учебные занятия, такие как плавание, игры и т. Д., Они могут быть выражены через интерфейс.

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

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

Взгляните на статью:http://shoaibmk.blogspot.com/2011/09/abstract-class-is-class-which-cannot-be.html

 22 сент. 2017 г., 11:05
Лучшее определение ..

Ваш ответ на вопрос