On m'a posé une question, je voulais que ma réponse soit revue ici.
Q: Dans quel scénario il est plus approprié d’étendre une classe abstraite plutôt que de mettre en œuvre la ou les interfaces?
A: Si nous utilisons un modèle de conception de méthode de modèle.
Ai-je raison ?
Je suis désolé si je n’ai pas pu formuler clairement la question.
Je connais la différence fondamentale entre la classe abstraite et l'interface.
1) utiliser une classe abstraite lorsque l'exigence est telle qu'il est nécessaire d'implémenter la même fonctionnalité dans chaque sous-classe pour une opération spécifique (implémenter la méthode) et une fonctionnalité différente pour certaines autres opérations (signatures de méthode uniquement)
2) utilisez l’interface si vous souhaitez que la signature soit identique (et différente de la mise en œuvre) pour pouvoir vous conformer à la mise en oeuvre de l’interface
3) on peut étendre au maximum une classe abstraite, mais peut implémenter plus d'une interface
Réitérant la question: Existe-t-il d’autres scénarios, en plus de ceux mentionnés ci-dessus, dans lesquels nous devons spécifiquement utiliser une classe abstraite (l’un est de voir si le modèle de conception de la méthode de modèle est basé sur ce concept uniquement)?
Interface vs classe abstraite
Le choix entre ces deux options dépend vraiment de ce que vous voulez faire, mais heureusement pour nous, Erich Gamma peut nous aider un peu.
Comme toujours, il y a un compromis, une interface vous donne la liberté par rapport à la classe de base, une classe abstraite vous donne la liberté d'ajouter de nouvelles méthodes plus tard . - Erich Gamma
Vous ne pouvez pas changer une interface sans avoir à changer beaucoup d'autres choses dans votre code, le seul moyen d'éviter cela serait donc de créer une toute nouvelle interface, ce qui pourrait ne pas toujours être une bonne chose. .
Abstract classes
devrait principalement être utilisé pour des objets étroitement liés. Interfaces
fournit mieux des fonctionnalités communes pour les classes non liées.
Quand utiliser les interfaces
Une interface permet à quelqu'un de commencer à partir de zéro pour implémenter votre interface ou implémenter votre interface dans un autre code dont le but initial ou principal était assez différent de votre interface. Pour eux, votre interface n'est qu'accidentelle, ce qui doit être ajouté à leur code pour pouvoir utiliser votre paquet. L'inconvénient est que chaque méthode de l'interface doit être publique. Vous pourriez ne pas vouloir tout exposer.
Quand utiliser les classes abstraites
Une classe abstraite, en revanche, fournit plus de structure. Il définit généralement certaines implémentations par défaut et fournit des outils utiles pour une implémentation complète. Le problème, c’est que le code qui l’utilise doit utiliser votre classe comme base. Cela peut être très gênant si les autres programmeurs souhaitant utiliser votre paquet ont déjà développé leur propre hiérarchie de classes de manière indépendante. En Java, une classe ne peut hériter que d’une classe de base.
Quand utiliser les deux
Vous pouvez offrir le meilleur des deux mondes, une interface et une classe abstraite. Les développeurs peuvent ignorer votre classe abstraite s'ils le souhaitent. Le seul inconvénient est que l'appel de méthodes via leur nom d'interface est légèrement plus lent que leur appel via leur nom de classe abstraite.
réitérant la question: il existe un autre scénario en plus de ceux mentionnés ci-dessus dans lesquels nous devons spécifiquement utiliser une classe abstraite (l'un est voir si le modèle de conception de méthode de modèle est basé sur ce concept uniquement)
Oui, si vous utilisez JAXB. Il n'aime pas les interfaces. Vous devez utiliser des classes abstraites ou contourner cette limitation avec des génériques.
D'un blog personnel post :
Interface:
En général, les interfaces doivent être utilisées pour définir les contrats (ce qui doit être réalisé, et non pas comment le réaliser).
Classe abstraite:
Les classes abstraites doivent être utilisées pour une implémentation (partielle). Ils peuvent constituer un moyen de restreindre la manière dont les contrats d'API doivent être mis en œuvre.
L'interface est utilisée lorsque vous avez un scénario selon lequel toutes les classes ont la même structure mais présentent des fonctionnalités totalement différentes.
La classe abstraite est utilisée lorsque vous avez un scénario selon lequel toutes les classes ont la même structure mais certaines fonctionnalités sont identiques.
Jetez un coup d'œil à l'article: http://shoaibmk.blogspot.com/2011/09/abstract-class-is-class-which-cannot-be.html
Lequel devriez-vous utiliser, des classes abstraites ou des interfaces?
Envisagez d'utiliser des classes abstraites si l'une de ces déclarations s'applique à votre scénario:
Vous souhaitez partager du code entre plusieurs classes étroitement liées.
Vous vous attendez à ce que les classes qui étendent votre classe abstraite aient de nombreuses méthodes ou champs communs, ou nécessitent des modificateurs d'accès autres que public (tels que protected et private).
Vous voulez déclarer des champs non statiques ou non finaux. Cela vous permet de définir des méthodes pouvant accéder à et modifier l'état de l'objet auquel elles appartiennent.
Envisagez d'utiliser des interfaces si l'une de ces déclarations s'applique à votre situation:
Vous vous attendez à ce que des classes non liées implémentent votre interface . Par exemple, les interfaces Comparable et Cloneable sont implémentées par de nombreuses classes non liées.
Vous souhaitez spécifier le comportement d'un type de données particulier, sans vous soucier de savoir qui l'implémente.
Vous souhaitez tirer parti de l'héritage multiple de type.
http://docs.Oracle.com/javase/tutorial/Java/IandI/abstract.html
Les choses ont beaucoup changé au cours des trois dernières années avec l’ajout de nouvelles fonctionnalités d’interface avec Java 8.
De la documentation Oracle page sur l'interface:
Une interface est un type de référence, similaire à une classe, qui ne peut contenir que des constantes, des signatures de méthodes, des méthodes default, des méthodes statiques et des types imbriqués. Les corps de méthodes n'existent que pour les méthodes par défaut et les méthodes statiques.
Comme vous l'avez indiqué dans votre question, la classe abstraite convient le mieux à modèle de méthode de modèle dans lequel vous devez créer un squelette. L'interface ne peut pas être utilisée ici.
Une autre considération pour préférer la classe abstraite à l'interface:
Vous n'avez pas d'implémentation dans la classe de base et seules les sous-classes doivent définir leur propre implémentation. Vous avez besoin d'une classe abstraite au lieu d'une interface puisque vous souhaitez partager un état avec des sous-classes.
La classe abstraite établit "est une" relation entre les classes liées et l'interface fournit "a une" capacité entre des classes non liées.
Deuxième partie de votre question, valable pour la plupart des langages de programmation, y compris Java, antérieure à la version Java-8.
Comme toujours, il y a un compromis, une interface vous donne la liberté par rapport à la classe de base, une classe abstraite vous donne la liberté d'ajouter de nouvelles méthodes plus tard. - Erich Gamma
Vous ne pouvez pas modifier une interface sans avoir à changer beaucoup de choses dans votre code
Si vous préférez que la classe abstraite s'interface plus tôt avec les deux considérations ci-dessus, vous devez repenser maintenant en tant que méthodes par défaut ont ajouté de puissantes fonctionnalités aux interfaces.
Les méthodes par défaut vous permettent d'ajouter de nouvelles fonctionnalités aux interfaces de vos bibliothèques et d'assurer la compatibilité binaire avec le code écrit pour les versions antérieures de ces interfaces.
Pour sélectionner l'un d'entre eux entre l'interface et la classe abstraite, consultez la documentation Oracle page quote qui:
Les classes abstraites sont similaires aux interfaces. Vous ne pouvez pas les instancier, et elles peuvent contenir un mélange de méthodes déclarées avec ou sans implémentation. Toutefois, avec les classes abstraites, vous pouvez déclarer des champs non statiques et finaux et définir des méthodes concrètes publiques, protégées et privées.
Avec les interfaces, tous les champs sont automatiquement publics, statiques et finaux, et toutes les méthodes que vous déclarez ou définissez (en tant que méthodes par défaut) sont publiques. De plus, vous ne pouvez étendre qu'une seule classe, qu'elle soit abstraite ou non, alors que vous pouvez implémenter un nombre illimité d'interfaces.
Reportez-vous à ces questions connexes pour plus de détails:
Interface vs Abstract Class (OO général)
Comment aurais-je dû expliquer la différence entre une classe d'interface et une classe abstraite?
En résumé: La balance penche davantage vers les interfaces}.
Existe-t-il d’autres scénarios, en plus de ceux mentionnés ci-dessus, dans lesquels nous avons spécifiquement besoin d’utiliser une classe abstraite (l’un est de voir si le modèle de conception de la méthode template est basé sur ce concept uniquement)?
Certains modèles de conception utilisent des classes abstraites (sur des interfaces) en plus du modèle de méthode Template.
Modèles de création:
(Structures structurelles:} _
Modèles comportementaux:
Vous n'êtes pas correct Il y a beaucoup de scénarios. Il n'est tout simplement pas possible de le réduire à une seule règle de 8 mots.
À mon avis, la différence fondamentale est que an interface can't contain non abstract methods while an abstract class can
. Ainsi, si les sous-classes partagent un comportement commun, ce comportement peut être implémenté dans la super-classe et donc hérité dans les sous-classes.
J'ai également cité ce qui suit dans le livre "Conception de l'architecture logicielle en Java"
"Dans le langage de programmation Java, l'héritage multiple n'est pas pris en charge . Cela signifie qu'une classe ne peut hériter que d'une seule classe. Par conséquent, l'héritage Ne doit être utilisé que lorsque cela est absolument nécessaire. Chaque fois que cela est possible, les méthodes denoter le comportement commun doit être déclaré sous la forme d’une interface Java être implémenté par différentes classes d’implémentation. Mais les interfaces souffrent de la limitation de leur incapacité à fournir des implémentations de méthodes. Cela signifie que chaque implémenteur. d’une interface doit implémenter explicitement toutes les méthodes déclarées dans une interface, même lorsque certaines de ces méthodes représentent la partie invariable de la fonctionnalité et ont exactement la même implémentation dans toutes les classes de l’implémenteur, ce qui conduit à un code redondant. L’exemple suivant montrecomment utiliser le modèle de classe parent abstraite dans de tels cas sans que Ne nécessite la mise en œuvre de méthodes redondantes. "
La réponse la plus courte est extend abstract class lorsque certaines des fonctionnalités recherchées y sont déjà implémentées.
Si vous implémentez l'interface, vous devez implémenter toute la méthode. Mais pour les classes abstraites, le nombre de méthodes à implémenter peut être inférieur.
Dans modèle de conception , un comportement doit être défini. Ce comportement dépend d'autres méthodes qui sont abstraites. En créant des sous-classes et en définissant ces méthodes, vous définissez le comportement principal. Le comportement sous-jacent ne peut pas être dans une interface car l'interface ne définit rien, elle se contente de déclarer. Ainsi, un modèle de conception de modèle vient toujours avec une classe abstraite. Si vous souhaitez conserver le flux du comportement intact, vous devez étendre la classe abstraite mais ne pas remplacer le comportement principal.
Les classes abstraites se distinguent des interfaces par deux aspects importants
Il y a beaucoup de bonnes réponses ici, mais je trouve souvent que le meilleur chemin consiste à utiliser les deux interfaces et classes abstraites. Considérons cet exemple artificiel:
Vous êtes développeur de logiciels dans une banque d’investissement et vous devez créer un système qui place les commandes sur le marché. Votre interface capture l’idée la plus générale de ce qu’un système commercial fait,
1) Trading system places orders
2) Trading system receives acknowledgements
et peut être capturé dans une interface, ITradeSystem
public interface ITradeSystem{
public void placeOrder(IOrder order);
public void ackOrder(IOrder order);
}
Désormais, les ingénieurs travaillant au point de vente et dans d’autres secteurs d’activité peuvent commencer à utiliser une interface avec votre système pour ajouter la fonctionnalité de placement des commandes à leurs applications existantes. Et vous n'avez même pas encore commencé à construire! C'est le pouvoir des interfaces.
Alors vous allez de l'avant et construisez le système pour stock traders; ils ont entendu dire que votre système dispose d'une fonctionnalité permettant de trouver des actions à bas prix et qu'ils sont très impatients de l'essayer! Vous capturez ce comportement dans une méthode appelée findGoodDeals()
, mais vous réalisez également que la connexion aux marchés comporte de nombreux problèmes. Par exemple, vous devez ouvrir une 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);
}
Les implémentations concrètes vont avoir beaucoup de ces méthodes compliquées comme connectToMarket()
, mais findGoodDeals()
est l’ensemble des préoccupations des traders.
Maintenant, voici où les classes abstraites entrent en jeu. Votre patron vous informe que les traders de devises veulent également utiliser votre système. Et en regardant les marchés des devises, vous voyez que la plomberie est presque identique aux marchés boursiers. En fait, connectToMarket()
peut être réutilisé intégralement pour se connecter aux marchés des changes. Cependant, findGoodDeals()
est un concept très différent dans le domaine des devises. Donc, avant de transmettre la base de code au spécialiste des opérations de change à travers l’océan, vous devez d’abord réfléchir à une classe abstract
, en laissant findGoodDeals()
non implémenté.
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>
}
Votre système de négociation d'actions implémente findGoodDeals()
comme vous l'avez déjà défini,
public class StockTradeSystem extends ABCTradeSystem{
public void findGoodDeals();
deals = <apply magic wizardry>
System.out.println("The best stocks to buy are: " + deals);
}
mais à présent, l’aspirant FX peut construire son système en fournissant simplement une implémentation de findGoodDeals()
pour les devises; elle n'a pas à réimplémenter les connexions socket ni même les méthodes d'interface!
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);
}
La programmation sur une interface est puissante, mais des applications similaires réimplémentent souvent les méthodes de manière identique. L'utilisation d'une classe abstraite évite les réimplémentations, tout en préservant la puissance de l'interface.
Remarque: on peut se demander pourquoi findGreatDeals()
ne fait pas partie de l'interface. N'oubliez pas que l'interface définit les composants les plus généraux d'un système commercial. Un autre ingénieur peut développer un système commercial COMPLETEMENT DIFFÉRENT, où ils ne se soucient pas de trouver de bonnes offres. L'interface garantit que le bureau des ventes peut également s'interfacer avec son système. Il est donc préférable de ne pas embrouiller votre interface avec des concepts d'application tels que "des offres exceptionnelles".
C'est une bonne question. Les deux ne sont pas similaires mais peuvent être utilisés pour les mêmes raisons, comme une réécriture. Lors de la création, il est préférable d'utiliser Interface. En classe, c'est bon pour le débogage.
Ceci est ma compréhension, espérons que cela aide
Classes abstraites:
Interfaces:
Abstract classes should be extended when you want to some common behavior to get extended
. La super classe abstraite aura le comportement commun et définira le comportement spécifique de la méthode abstraite que les sous-classes doivent implémenter.
Interfaces allows you to change the implementation anytime allowing the interface to be intact
.
Utilisation du résumé et de l'interface:
L'un a "Est-Une-relation" et un autre a "Has-Une-relation"
Les propriétés par défaut sont définies dans abstract et des propriétés supplémentaires peuvent être exprimées via l'interface.
Exemple: -> Chez les êtres humains, nous avons certaines propriétés par défaut qui mangent, dorment, etc. mais si quelqu'un a d'autres activités comme la natation, le jeu, etc., celles-ci peuvent être exprimées par Interface.
Classe abstraite
interfaces