Pourquoi sont des interfaces privilégiées pour les classes abstraites?
J'ai récemment assisté à une entrevue et ils m'ont posé la question "Pourquoi les Interfaces sont privilégiées sur les classes Abstraites?"
J'ai essayé de donner quelques réponses comme:
- On ne peut obtenir que l'on Étend les fonctionnalités
- ils sont 100% Abstrait
- Mise en œuvre n'est pas codé en dur
Ils m'ont demandé de prendre tout de l'api JDBC que vous utilisez. "Pourquoi sont-ils Interfaces?".
Puis-je obtenir une meilleure solution pour cela?
- Je suis presque sûr que j'ai vu une question comme ça avant, mais même pas Google peut trouver. Peut-être mon esprit qui me joue des tours encore.
- Note: j'ai édité le titre pour la grammaire, j'ai quitté le corps, car elle semble être des citations, et peut-être qu'ils ne le dire comme ça.
- C'est une question piège, car il suppose une position sur le sujet et ne donne aucun contexte dans lequel il "peut" être valide. Je suis d'accord avec devinb sur celui-ci. Ils sont à la fois des outils - utiliser de façon appropriée. Trop de réponses ici de justifier la question...qui peut être acceptable si vous voulez vraiment le travail.
- Ne te justifie pas la question avec une réponse. Ce n'est pas ce qu'ils sont (bien, devrait être à la recherche pour. Montrer que vous savez de quoi vous parlez, et peuvent faire le travail. Si ils sont en vaut la peine, ils ne sont pas à la recherche d'un perroquet.
- Voir mon commentaire ci-dessous .. mais à chaque fois que je reçois une réponse comme la tienne, le candidat obtient un glacial "merci pour votre temps". La réponse montre pas la profondeur de la compréhension.
- De commencer la rédaction de cas de tests ou d'aller le TDD route et vous trouverez que la rédaction de cas de tests est beaucoup plus facile lors de l'utilisation d'interfaces. Il permet de se moquer de tout ce que vous n'avez pas besoin pour votre cas de test.
- double possible de Interface vs Classe Abstraite (général OO)
- Double Possible de Quand utiliser une interface au lieu d'une classe abstraite, et vice-versa?
Vous devez vous connecter pour publier un commentaire.
Que les questions de l'entrevue reflète une certaine croyance de la personne qui pose la question. Je crois que la personne qui est mal, et, par conséquent, vous pouvez aller de l'une des deux directions.
La réponse qu'ils veulent, eh bien, les autres affiches ont mis en évidence ces incroyablement bien.
Plusieurs héritage de l'interface, l'héritage des forces de la classe à faire des choix d'implémentation, les interfaces peuvent être modifiées plus facilement.
Toutefois, si vous créez un convaincant (et corriger) argument dans votre désaccord, alors l'enquêteur peut en prendre note.
Tout d'abord, mettre en évidence les choses positives sur les interfaces, c'est un must.
Ensuite, je tiens à dire que les interfaces sont mieux dans de nombreux scénarios, mais ils ont aussi conduire à la duplication de code, qui est quelque chose de négatif. Si vous disposez d'un large éventail de sous-classes qui sera fait en grande partie la même mise en œuvre, en plus des fonctionnalités supplémentaires, vous souhaitez peut-être une classe abstraite. Il vous permet d'avoir beaucoup de semblables objets avec précision, le détail, alors qu'avec uniquement des interfaces, vous devez avoir de nombreux objets distincts avec près de dupliquer du code.
Interfaces ont de nombreuses utilisations, et il existe une raison valable de croire qu'ils sont "mieux". Cependant, vous devez toujours utiliser le bon outil pour le travail, et cela signifie que vous ne pouvez pas écrire hors de classes abstraites.
En général, et ce n'est pas une "règle" qui devrait être suivi aveuglément, le plus souple est:
L'interface est là pour un couple de raisons:
Cela signifie que vous pouvez prendre les pré-existants des classes (ou simplement des classes qui DOIT s'étendre à partir de quelque chose d'autre) et demandez-leur de travailler avec votre code.
La classe abstraite est là pour vous fournir toutes les parties communes pour les classes concrètes. La classe abstraite de l'extension lors de l'écriture de nouvelles classes ou de la modification de classes que vous voulez l'étendre (en supposant qu'ils s'étendent à partir de java.lang.De l'objet).
Vous devriez toujours (sauf si vous avez une très bonne raison de ne pas déclarer de variables (exemple, la classe, le local, et les paramètres de la méthode) de l'interface.
Vous obtenez seulement un coup à l'héritage. Si vous faites une classe abstraite plutôt que d'une interface, quelqu'un qui hérite de la classe peut pas hériter d'une autre classe abstraite.
Vous pouvez mettre en œuvre plus d'une interface, mais vous ne peut hériter que d'une seule classe
Les Classes Abstraites
1.Ne peut pas être instanciée indépendamment de leurs classes dérivées. Classe abstraite les constructeurs sont appelés par leurs classes dérivées.
2.Définir résumé signatures de membres que les classes de base doit mettre en œuvre.
3.Sont plus extensible que les interfaces, sans violer aucune compatibilité de version. Les classes abstraites, il est possible d'ajouter d'autres non-abstraites, les membres de toutes les classes dérivées peuvent hériter.
4.Peut inclure des données stockées dans les champs.
5.Permettre (virtuel) que les membres de la mise en œuvre et, par conséquent, de fournir une implémentation par défaut d'un membre de l'dérivant de la classe.
6.Dérivée d'une classe abstraite utilise une sous-classe, le seul de la classe de base option.
Interface
1.Ne peut pas être instanciée.
2.La mise en œuvre de tous les membres de l'interface se produit dans la classe de base. Il n'est pas possible de mettre en œuvre seuls quelques membres dans la mise en œuvre de la classe.
3.L'extension des interfaces avec d'autres membres casse la compatibilité de version.
4.Ne peut pas stocker de données. Les champs peuvent être spécifiée uniquement sur le dérivant des classes. La solution de contournement pour ce qui est de définir des propriétés, mais sans mise en œuvre.
5.Tous les membres sont automatiquement virtuel et ne peut pas inclure toute mise en œuvre.
6.Bien qu'aucun défaut de mise en œuvre peuvent apparaître, les classes qui implémentent les interfaces peuvent continuer à dériver l'un de l'autre.
Comme devinb et d'autres mentionnent, il semble que l'enquêteur montre leur ignorance de ne pas accepter votre réponse valable.
Toutefois, la mention de JDBC peut-être un indice. Dans ce cas, peut-être qu'ils demandent pour les avantages d'un client de codage par rapport à une interface au lieu d'une classe.
Donc au lieu de tout à fait valide les réponses telles que "vous n'aurez qu'une seule utilisation de l'héritage", qui sont relatives à la conception de classe, ils peuvent être à la recherche pour une réponse plus comme "découple un client à partir d'une mise en œuvre spécifique".
Les classes abstraites ont un certain nombre de pièges potentiels. Par exemple, si vous remplacez une méthode, la
super()
méthode n'est pas appelée à moins que vous ne l'appelez. Cela peut causer des problèmes pour les mal-mise en œuvre ecraser les classes. Aussi, il y a des problèmes potentiels avecequals()
lorsque vous utilisez l'héritage.L'utilisation d'interfaces peuvent encourager l'utilisation de la composition lorsque vous souhaitez partager une mise en œuvre. La Composition est très souvent une meilleure façon de réutiliser les autres objets, car il est moins cassant. L'héritage est facilement surutilisation ou utilisés à mauvais escient.
Définir une interface est un moyen très sûr pour définir la façon dont un objet est censé agir, sans risquer de la fragilité que peut venir avec d'étendre une autre classe, abstraite ou non.
Aussi, comme vous le mentionnez, vous ne pouvez étendre une classe à un moment, mais vous pouvez implémenter autant d'interfaces que vous le souhaitez.
Les classes abstraites sont utilisés lorsque vous héritez mise en œuvre, les interfaces sont utilisées lorsque vous héritez spécification. JDBC normes de l'état que "Une connexion doit faire ce". C'est la spécification.
Lorsque vous utilisez les classes abstraites vous créer un couplage entre la sous-classe et de la classe de base. Ce couplage peut parfois rendre le code vraiment dur à changer, surtout que le nombre de sous-classes augmente. Les Interfaces n'ont pas ce problème.
Vous aussi avoir seulement un héritage, de sorte que vous devez vous assurer que vous utilisez pour la bonne raisons.
Les autres postes ont fait un excellent travail de regarder les différences entre les interfaces et les classes abstraites, donc je ne vais pas reproduire ces pensées.
Mais en regardant la question de l'entrevue, la question est vraiment "Quand devrait interfaces de préférence sur les classes abstraites?" (et vice versa).
Comme avec la plupart des constructions de programmation, ils sont disponibles pour une raison absolue et des déclarations comme celle de la question de l'entrevue ont tendance à manquer ça. Il sorte de me rappelle de toutes les déclarations que vous avez utilisé pour lire sur la goto déclaration C. "Vous ne devez jamais utiliser goto - il révèle un mauvais codage des compétences." Cependant, goto toujours eu ses utilisations appropriées.
Respectueusement en désaccord avec la plupart des affiches ci-dessus (désolé! mod-moi si vous voulez 🙂 )
Tout d'abord, la "seule super-classe" la réponse est boiteux. N'importe qui qui m'a donné cette réponse dans un entretien serait rapidement répliqué avec "C++ existait avant Java et C++ a plusieurs super-classes. Pourquoi pensez-vous que James Gosling seulement permis à un super-classe pour Java?"
Comprendre la philosophie derrière votre réponse sinon vous êtes grillé (au moins, si je vous interviewer.)
Deuxième, les interfaces ont plusieurs avantages sur les classes abstraites, en particulier lors de la conception d'interfaces. Le plus important est de ne pas avoir une classe particulière de la structure imposée à l'appelant d'une méthode. Il n'y a rien de pire que d'essayer d'utiliser un appel de méthode qui exige une structure de classe. Elle est douloureuse et inconfortable. À l'aide d'une interface rien peut être transmis à la méthode avec un minimum d'attentes.
Exemple:
vs
Pour l'ancien, l'appelant sera toujours de prendre leur structure de données existantes et l'écraser sur une nouvelle table de hachage.
Troisième, interfaces permettent méthodes publiques de la classe de béton les responsables de l'implémentation d'être "privé". Si la méthode n'est pas déclarée dans l'interface, puis la méthode ne peut pas être utilisé ou mal utilisé) par les classes qui n'ont pas d'affaires à l'aide de la méthode. Ce qui m'amène au point 4....
Quatrième, les Interfaces représentent un contrat minimal entre la mise en œuvre de la classe et de l'appelant. Ce contrat minimal spécifie exactement comment le béton maître d'œuvre s'attend à être utilisée, et pas plus. La classe d'appel n'est pas autorisé à utiliser toute autre méthode non spécifiée par le "contrat" de l'interface. Le nom de l'interface à utiliser aussi les saveurs du développeur espérance de la façon dont ils devraient être à l'aide de l'objet. Si un développeur est passé d'un
Le développeur sait que la seule méthode qu'ils peuvent appeler la visite de la méthode. Ils ne vous laissez pas distraire par le brillant des méthodes dans la classe de béton qu'il ne faut pas jouer avec.
Enfin, les classes abstraites ont de nombreuses méthodes qui sont vraiment présents uniquement pour les sous-classes à utiliser. Donc les classes abstraites ont tendance à regarder un peu comme un bazar à l'extérieur de développeur, il n'y a pas de directives sur les méthodes qui sont destinés à être utilisés en dehors du code.
Oui, bien sûr, certaines de ces méthodes peuvent être faites protégé. Toutefois, malheureusement, protégé méthodes sont également visibles par les autres classes du même package. Et si un résumé, la méthode de la classe implémente une interface, la méthode doit être public.
Cependant, l'utilisation des interfaces de toutes ces entrailles qui sont suspendus lorsque l'on regarde le résumé super classe ou la classe de béton sont en sécurité à l'écart.
Oui, je sais que, bien sûr, le développeur peut utiliser certains "spécial" de la connaissance à associer un objet à un autre plus large de l'interface ou de la classe de béton lui-même. Mais un tel casting viole le contrat prévu, et le développeur doit être giflé avec un saumon.
Si ils pensent que X est mieux que Y je ne serais pas inquiet pour obtenir le travail, je ne voudrais pas travailler pour quelqu'un qui m'a forcé à un dessin sur un autre, parce qu'ils ont dit les interfaces sont les meilleurs. Les deux sont bons en fonction de la situation, sinon pourquoi la langue choisir d'ajouter les classes abstraites? Sûrement, la langue, les concepteurs sont plus intelligents que moi.
C'est la question de "l'Héritage Multiple".
On peut "s'étend" pas plus d'un abstarct classe à la fois par une autre classe, mais dans les Interfaces, on peut "mettre en œuvre" des interfaces multiples en classe unique.
Donc, bien que Java ne fournit pas d'héritage multiple en général, mais en utilisant les interfaces nous pouvons intégrer multiplt l'héritage de la propriété en elle.
Espérons que cette aide!!!
interface
s sont d'une façon plus propre de l'écriture purement abstraite de la classe. Vous pouvez dire que la mise en œuvre n'a pas glissé (bien sûr, vous pouvez le faire à certaines étapes de maintenance, ce qui rend les interfaces mauvais). C'est à ce sujet. Il n'y a presque pas de différence perceptible pour le code client.JDBC est un très mauvais exemple. Demandez à quelqu'un qui a essayé de mettre en œuvre les interfaces et maintenir le code entre les versions JDK. JAX-WS est encore pire, ajouter des méthodes dans les versions de mise à jour.
Il existe des différences techniques, telles que la capacité de se multiplier "héritent" de l'interface. Qui tend à être le résultat de confondre design. Dans de rares cas, il peut être utile de disposer d'une mise en œuvre de la hiérarchie qui est différente de l'interface de la hiérarchie.
Sur le revers de la médaille pour les interfaces, le compilateur n'est pas en mesure de choisir jusqu'à certains impossible jette/
instanceof
s.Il y a une raison non mentionnée ci-dessus.
Vous pouvez décorer une interface facilement avec java.lang.de réfléchir.Proxy vous permettant d'ajouter du code personnalisé au moment de l'exécution de n'importe quelle méthode de l'interface donnée. Il est très puissant.
Voir http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html pour un tutoriel.
interface n'est pas un substitut pour classe abstraite.
Préfèrent
interface: À l'exécution d'un contrat par de multiples objets indépendants
classe abstraite: Pour mettre en œuvre les mêmes ou différents comportements entre plusieurs objets liés à l'
Reportez-vous à cette question SE pour les cas d'utilisation à la fois de l'interface et la classe abstraite
Interface vs Classe Abstraite (général OO)
Cas d'utilisation:
Si vous devez utiliser Template_method modèle, vous ne pouvez pas atteindre avec l'interface. Classe abstraite doit être choisi pour le réaliser.
Si vous avez de mettre en œuvre une capacité pour de nombreux unrleated objets, la classe abstraite n'est pas le but et que vous avez choisi interface.
Vous pouvez implémenter plusieurs interfaces, mais surtout avec c# vous ne pouvez pas avoir plusieurs héritages
Parce que les interfaces ne sont pas en train de vous forcer dans certains hiérarchie d'héritage.
Vous de définir des interfaces lorsque vous n'avez besoin que d'un objet de mettre en œuvre certaines méthodes, mais vous ne se soucient pas de son pedigree. Si quelqu'un peut étendre une classe existante pour mettre en œuvre une interface sans toucher à l'existant précédemment, le comportement de cette classe.
C'est pourquoi JDBC est toutes les interfaces; vous n'avez pas vraiment attention à ce que les classes sont utilisées dans JDBC à la mise en œuvre, vous avez seulement besoin de tout JDBC mise en œuvre pour avoir le même comportement attendu. En interne, l'Oracle JDBC driver peut être très différent de l'PostgreSQL pilote, mais c'est pas pertinent pour vous. On peut hériter de certaines classes internes que la base de données, les développeurs avaient déjà, tandis qu'un autre peut être entièrement développé à partir de zéro, mais ce n'est pas important pour vous aussi longtemps qu'ils mettent en œuvre les mêmes interfaces de sorte que vous pouvez communiquer avec l'un ou l'autre sans en connaître le fonctionnement interne de l'un ou l'autre.
Bien, je crois que la question devrait être reformulée. Les Interfaces sont principalement des contrats d'une classe de l'acquisition, de la mise en œuvre de ce contrat lui-même peut varier. Une classe abstraite contient généralement des valeurs par défaut de la logique et de son enfant des classes d'ajouter un peu plus de logique.
Je dirais que la réponse aux questions qui s'appuie sur le diamant problème. Java empêche l'héritage multiple pour l'éviter. ( http://en.wikipedia.org/wiki/Diamond_problem ).
Ma réponse à cette question précise est :
SOLEIL ne sait pas comment les mettre en œuvre ou de ce qui, dans la mise en œuvre. C'est l'prestataires de services/db fournisseurs à mettre leur logique dans la mise en œuvre.
JDBC conception a relation avec le Pont de modèle, qui dit "détacher une abstraction de sa mise en œuvre afin que les deux peuvent varier de manière indépendante".
Qui signifie api JDBC interfaces hiérarchie peut être évolué indépendamment de la mise en œuvre de la hiérarchie qu'un fournisseur jdbc fournit ou utilise.
Les classes abstraites proposent un moyen de définir un modèle de comportement, où l'utilisateur plugins dans les détails.
En est un bon exemple de Java 6 SwingWorker. Elle définit un cadre pour faire quelque chose dans le fond, demandant à l'utilisateur de définir doInBackground() pour la tâche réelle.
J'ai étendu cette classe tel qu'il a créé automatiquement une fenêtre de la barre de progression. J'ai remplacé done(), pour le contrôle de l'élimination de ce pop-up, mais ensuite un nouveau point de remplacer, permettant à l'utilisateur pour éventuellement définir ce qui se passe après la barre de progression disparaît.
L'utilisateur a l'obligation de fournir à la mise en œuvre de doInBackground(). Cependant, ils peuvent aussi avoir suivi le comportement, tels que l'ouverture d'une autre fenêtre, l'affichage d'un JOptionPane avec les résultats, ou simplement ne rien faire.
Pour l'utiliser:
Cela montre comment une classe abstraite peut bien fournir basé sur un modèle de fonctionnement, orthogonale à la notion d'interfaces de définir une API contrat.
Sa dépend de votre exigence et la puissance de la mise en œuvre, ce qui est très important.
Vous avez donc beaucoup de réponse à ce sujet.
Ce que je pense sur cette question est que la classe abstraite est l'évolution du si de l'API.
Vous pouvez définir votre avenir définition de la fonction dans la classe abstraite mais vous n'avez pas besoin de toutes les fonctions de mise en œuvre dans votre classe principale, mais avec l'interface tu ne peux pas faire cette chose.