Pourquoi utiliser des Interfaces, héritage Multiple vs Interfaces, avantages des Interfaces?
j'ai encore un peu de confusion à ce sujet. Ce que j'ai trouvé jusqu'à présent est
(des questions similaires ont déjà été posées ici, mais j'avais d'autres points en tête.)
de l'Interface est la collection des SEULES méthodes abstraites et finales des champs.
il n'y a pas d'héritage multiple en Java.
Les Interfaces peuvent être utilisées pour obtenir un héritage multiple en Java.
un point fort de L'héritage est que nous pouvons utiliser le code de la classe de base dans la classe dérivée sans l'écrire à nouveau. Peut-être que c'est la chose la plus importante pour l'héritage.
maintenant..
Q1. Comme les interfaces n'ont que des méthodes abstraites (pas de code), Comment Pouvons-nous disons que si nous implémentons n'importe quelle interface alors c'est un héritage ? Nous ne sommes pas à l'aide de son code.
Q2. Si implémenter une interface n'est pas un héritage, alors comment les interfaces sont-elles utilisées pour obtenir un héritage multiple ?
Q3. En tout cas, quel est l'avantage d'utiliser des Interfaces ? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre.
alors pourquoi créer des interfaces ?
NOTE: j'ai trouvé un cas où les interfaces sont utiles. Un exemple de cela est comme dans Runnable interface nous avons public void run() méthode dans laquelle nous définissons la fonctionnalité de thread et il est construit dans le codage que cette méthode sera exécutée comme un thread séparé. Donc nous avons juste besoin de coder ce qu'il faut faire dans thread, le reste est prédéfini. Mais cette chose peut aussi être réalisée en utilisant des classes abstraites et tout.
alors quels sont les avantages exacts de l'utilisation des interfaces? Est-ce vraiment un héritage Multiple que nous réalisons en utilisant des Interfaces?
11 réponses
Q1. Comme les interfaces n'ont que des méthodes abstraites (pas de code), Comment Pouvons-nous dire que si nous implémentons n'importe quelle interface alors c'est un héritage ? Nous ne sommes pas à l'aide de son code.
on ne peut pas. Les Interfaces ne sont pas utilisées pour obtenir un héritage multiple. Ils le remplacent par une construction plus sûre, bien que légèrement moins puissante. Notez le mot-clé implements
plutôt que extends
.
Q2. Si la mise en œuvre d'une interface n'est pas un héritage, alors comment les interfaces sont-elles utilisées pour obtenir un héritage multiple ?
ils ne le sont pas. Avec des interfaces, une seule classe peut avoir plusieurs " vues ", APIs différents ou des capacités. Par exemple: Une classe peut être Runnable
et Callable
en même temps, alors que les deux méthodes font effectivement la même chose.
Q3. De toute façon quel est l'avantage de l'utilisation de Les Interfaces ? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre.
Interfaces sont sorte d'héritage multiple avec aucun problème que ce dernier introduit (comme le problème de diamant ).
il y a peu de cas d'utilisation pour les interfaces:
-
Objet a effectivement deux identités: un
Tank
est à la fois unVehicle
et unWeapon
. Vous pouvez utiliser une instance deTank
où soit le premier soit le second est attendu (polymorphisme). C'est rarement le cas dans la vie réelle et est en fait un exemple où l'héritage multiple serait mieux (ou traits). -
Simple responsabilités: une instance de
Tank
objet dans un jeu, c'est aussiRunnable
pour vous permettre de l'exécuter dans un thread et unActionListener
pour répondre aux évènements de la souris. -
interfaces de rappel: si un objet implémente une interface de rappel, il est avisé de son cycle de vie ou d'autres événements.
-
interfaces marqueur: n'ajoutant aucune méthode, mais facilement accessibles via
instanceof
pour découvrir les capacités ou les souhaits de l'objet.Serializable
etCloneable
en sont des exemples.
ce que vous recherchez est trait (comme dans Scala), malheureusement indisponible en Java.
sont une collection de champs statiques finaux et de méthodes abstraites (Java 8 nouvellement ajouté le soutien d'avoir des méthodes statiques dans une interface).
Les Interfacessont créées dans des situations où nous savons qu'une tâche doit être effectuée, mais la façon de le faire peut varier. En d'autres termes, nous pouvons dire que nous implémentons des interfaces pour que notre classe commence à se comporter d'une manière particulière.
laissez-moi vous expliquer avec un exemple, nous savons tous ce que sont les animaux. Comme Le Lion est un animal de singe est un animal, l'éléphant est un animal, la vache est un animal, et ainsi de suite. Maintenant, on sait que tous les animaux mangent et dorment. Mais la façon dont chaque animal peut manger quelque chose ou dormir peut différer. Comme le Lion mange en chassant d'autres animaux où comme la vache mange l'herbe. Mais les deux manger. Donc nous pouvons avoir un pseudo code comme celui-ci,
interface Animal {
public void eat();
public void sleep();
}
class Lion implements Animal {
public void eat() {
// Lion's way to eat
}
public void sleep(){
// Lion's way to sleep
}
}
class Monkey implements Animal {
public void eat() {
// Monkey's way to eat
}
public void sleep() {
// Monkey's way to sleep
}
}
selon le pseudo-code mentionné ci-dessus, tout ce qui est capable de manger ou de dormir sera appelé un animal ou nous pouvons dire qu'il est must pour tous les animaux de manger et de dormir, mais de la façon de manger et de dormir dépend de l'animal.
dans le cas d'interfaces nous héritons seulement le comportement, pas le code réel comme dans le cas de l'héritage de classes.
Q1. Comme les interfaces n'ont que des méthodes abstraites (pas de code), Comment Pouvons-nous dire que si nous implémentons n'importe quelle interface alors c'est un héritage ? Nous ne sommes pas à l'aide de son code.
la mise en Œuvre de les interfaces autre type d'héritage. Il n'est pas similaire à l'héritage de classes comme dans cette classe d'enfant d'héritage obtient le vrai code à réutiliser de la classe de base.
Q2. Si implémenter une interface n'est pas un héritage, alors comment les interfaces sont-elles utilisées pour obtenir un héritage multiple ?
Il est dit parce qu'une classe peut implémenter plusieurs interfaces. Mais nous devons comprendre que cet héritage est différent de l'héritage des classes.
Q3. En tout cas, quel est l'avantage d'utiliser des Interfaces ? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre.
implémenter une interface met la contrainte sur la classe qu'elle doit surpasser toutes ses méthodes abstraites.
BAISER
j'ai cherché pendant des jours, des semaines en essayant de comprendre les interfaces et semble lire la même aide Générique; Je ne cherche pas à dénigrer les contributions, mais je pense que l'ampoule vient de cliqué donc je suis soufflé :))
je préfère le garder simple stupide, ainsi sera proffer ma nouvelle vue trouvée des interfaces.
je suis un codeur occasionnel mais je veux poster ce code que j'ai écrit dans VB.NET (le le principe est le même pour les autres langues), pour aider les autres à comprendre les interfaces.
si je me trompe, veuillez en informer les autres dans les commentaires de suivi.
explication
trois boutons sur un formulaire, en cliquant chacun sauve une référence de classe différente à la variable d'interface (_data). Le point entier de différentes références de classe dans une variable d'interface, est ce que je n'ai pas compris comme il semblait redondant, puis sa puissance devient évidente avec la msgbox, Je n'ai qu'à appeler la même méthode pour effectuer la tâche dont j'ai besoin, dans ce cas 'GetData()', qui utilise la méthode dans la classe qui est actuellement détenue par la variable de référence de l'interface (_data).
donc cependant je souhaite obtenir mes données (à partir d'une base de données, le web ou un fichier texte), il est seulement jamais fait en utilisant le même nom de méthode ; le code derrière cette mise en œuvre...je ne se soucient pas.
il est alors facile de changer chaque code de classe en utilisant l'interface sans aucune dépendance...c'est un objectif clé en OO et encapsulation.
quand utiliser
classes de Code et si vous remarquez le même verbe utilisé pour les méthodes, comme 'GetData()', alors c'est un bon candidat pour implémenter une interface sur cette classe et utiliser ce nom de méthode comme une abstraction / interface.
j'espère sincèrement que cela aide une camarade noob avec ce principe difficile.
Public Class Form1
Private _data As IData = Nothing
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
_data = New DataText()
MsgBox(_data.GetData())
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
_data = New DataDB()
MsgBox(_data.GetData())
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
_data = New DataWeb()
MsgBox(_data.GetData())
End Sub
End Class
Public Interface IData
Function GetData() As String
End Interface
Friend Class DataText : Implements IData
Friend Function GetData() As String Implements IData.GetData
Return "DataText"
End Function
End Class
Friend Class DataDB : Implements IData
Friend Function GetData() As String Implements IData.GetData
Return "DataDB"
End Function
End Class
Friend Class DataWeb : Implements IData
Friend Function GetData() As String Implements IData.GetData
Return "DataWeb"
End Function
End Class
c'est une question très ancienne et la version java-8 a ajouté plus de fonctionnalités et de puissance à l'interface.
une déclaration d'interface peut contenir
- signatures de méthode
- méthodes par défaut
- méthodes statiques
- définitions constantes.
les seules méthodes qui ont des implémentations dans l'interface sont des méthodes par défaut et statiques .
utilisations de l'interface:
- pour définir un contrat
- pour relier des classes sans rapport avec a un capacités (par exemple, les classes mettant en œuvre L'interface sérialisable peuvent avoir ou ne peuvent pas avoir de relation entre eux sauf la mise en œuvre de cette interface
- pour fournir interchangeable mise en œuvre, p.ex.
Strategy_pattern
- 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 anciennes versions de ces interfaces
- organisez des méthodes d'aide dans vos bibliothèques avec statique méthodes ( vous pouvez garder les méthodes statiques spécifiques à une interface dans la même interface, plutôt que dans une catégorie distincte)
jetez un oeil à cette question se liée pour exemple de code pour mieux comprendre les concepts:
comment aurais-je dû expliquer la différence entre une Interface et une classe abstraite?
pour répondre à vos questions:
Q1. Comme les interfaces n'ont que des méthodes abstraites (pas de code), Comment Pouvons-nous dire que si nous implémentons n'importe quelle interface alors c'est un héritage ? Nous ne sommes pas à l'aide de son code.
Q2. Si implémenter une interface n'est pas un héritage, alors comment les interfaces sont-elles utilisées pour obtenir un héritage multiple ?
Interface peut contenir le code pour statique et défaut méthodes. Ils les méthodes par défaut fournissent la compatibilité arrière et les méthodes statiques fournissent helper/utility fonctions.
vous ne pouvez pas avoir un véritable héritage multiple en java et l'interface n'est pas le moyen de l'obtenir. L'Interface ne peut contenir que des constantes. Donc vous ne pouvez pas hériter de l'état mais vous pouvez mettre en œuvre un comportement.
Vous pouvez remplacer héritage avec capacité "de la 151930920" . L'Interface fournit capacités multiples pour l'implémentation de classes.
Q3. En tout cas, quel est l'avantage d'utiliser des Interfaces ? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre.
reportez-vous à " utilise de l'interface "1519200920 section" " dans ma réponse.
Q1. Comme les interfaces n'ont que des méthodes abstraites (pas de code), Comment Pouvons-nous dire que si nous implémentons n'importe quelle interface alors c'est un héritage ? Nous ne sommes pas à l'aide de son code.
malheureusement, dans l'usage familier , le mot inheritance
est encore fréquemment utilisé lorsqu'une classe met en œuvre une interface, bien que interface implementation
serait un terme préférable-IMO, le terme inheritance
devrait être utilisé strictement avec héritage d'un classe concrète ou abstraite. Dans les langages comme C++ et C#, la même syntaxe (i.e. Subclass : Superclass
et Class : Interface
) est utilisée pour l'héritage de classe et l'implémentation d'interface, ce qui peut avoir contribué à la propagation de l'usage abusif du mot inheritance
avec des interfaces. Java a une syntaxe différente pour extend
ing une classe par opposition à implement
ing une interface, ce qui est une bonne chose.
Q2 si la mise en œuvre d'une interface n'est pas héréditaire alors comment les interfaces sont-elles utilisées pour obtenir l'héritage multiple ?
vous pouvez obtenir l '"effet" de l'héritage multiple par la composition - en implémentant plusieurs interfaces sur une classe, puis en fournissant des implémentations pour toutes les méthodes, propriétés et événements requis de toutes les interfaces sur la classe. Une technique courante de faire ceci avec des classes concrètes est de faire des relations "has-a" (composition) avec des classes qui mettent en œuvre les interfaces en "câblant" l'implémentation à chacune des implémentations de classe internes. (Des langages tels que C++ supportent directement plusieurs héritages concrets, mais cela crée d'autres problèmes potentiels comme le problème du diamant).
Q3 de toute façon, Quel est l'avantage d'utiliser des Interfaces ? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre.
Interfaces allow classes existantes (par exemple frameworks) pour interagir avec vos nouvelles classes sans les avoir jamais "vues" auparavant, en raison de la capacité de communiquer à travers une interface connue. Pensez à une interface comme un contrat. En mettant en œuvre cette interface sur une classe, vous êtes contractuellement tenu de respecter les obligations qui en découlent, et une fois ce contrat mis en œuvre, votre classe devrait pouvoir être utilisée de façon interchangeable avec tout autre code qui consomme l'interface.
Exemple Du Monde Réel
un exemple "réel" serait la législation et la convention (interface) entourant une prise murale électrique dans un pays particulier. Chaque appareil électrique branché à la prise doit respecter les spécifications (contractuelles) que les autorités ont définies pour la prise, par exemple la position de la ligne, des fils neutres et de terre, la position et la coloration de l'interrupteur marche / arrêt, et la conformité de la prise avec les spécifications de l'équipement électrique. la tension électrique, la fréquence et le courant maximum qui seront alimentés par le interface
lorsqu'il sera allumé.
l'avantage de découpler l'interface (c'est-à-dire une prise murale standard) plutôt que de simplement souder les fils ensemble est que vous pouvez brancher (et débrancher) un ventilateur, une bouilloire, un double adaptateur, ou un nouvel appareil qui sera inventé l'année prochaine, même si cet appareil n'existait pas lorsque l'interface a été conçue. Pourquoi? Parce qu'il va conforme aux exigences de l'interface.
Pourquoi utiliser des interfaces?
Interfaces sont grands pour le couplage lâche des classes, et sont l'un des piliers de L'oncle Bob solide paradigme, en particulier le Dependency Inversion Principle
et Interface Segregation Principles
.
simplement dit, en s'assurant que les dépendances entre classes sont couplées uniquement sur les interfaces (abstractions), et non sur d'autres classes concrètes, il permet de substituer la dépendance à toute autre implémentation de classe qui répond aux exigences de l'interface.
dans testing, les bouchons et les moqueries des dépendances peuvent être utilisés pour tester l'Unité de chaque classe, et l'interaction de la classe avec la dépendance peut être "spyed" sur.
héritage est quand une classe dérive d'une autre classe (qui peut être abstraite) ou une Interface. Le point le plus fort de l'orientation objet (héritage) n'est pas la réutilisation du code (il y a plusieurs façons de le faire), mais le polymorphisme.
polymorphisme est quand vous avez le code qui utilise l'interface, qui est l'objet instance peut être de n'importe quelle classe dérivée de cette interface. Par exemple je peux avoir une telle méthode: animal de compagnie(ianimal animal) et cette méthode obtiendra un objet qui est un exemple de chien ou de chat qui hérite de IAnimal. ou je peux avoir un code: Ianimal animal et puis je peux appeler une méthode de l'interface: animal.Eat () que le chien ou le chat peut mettre en œuvre d'une manière différente.
Le principal avantage des interfaces, c'est que vous pouvez hériter de certains d'entre eux, mais si vous avez besoin d'hériter d'un seul, vous pouvez utiliser une classe abstraite. Voici un article qui explique plus sur les différences entre une classe abstraite et interface: http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx
les deux méthodes fonctionnent (Interfaces et héritage Multiple).
Rapide Pratique À Réponse Courte
les Interfaces sont meilleures quand vous avez plusieurs années d'expérience en utilisant L'héritage Multiple qui ont des classes Super avec seulement la définition de méthode, et pas de code du tout.
une question complémentaire pourrait être:"comment et pourquoi migrer le code des Classes abstraites vers les Interfaces".
si vous n'avez pas beaucoup de classes abstraites, vous pouvez sauter les interfaces.
ne se précipite pas pour utiliser des interfaces.
Longue Et Ennuyeuse Réponse
Les Interfacessont très similaires, voire équivalentes à des Classes abstraites.
si votre code a beaucoup de classes abstraites, alors son temps vous commencez à penser en termes D'Interfaces.
le code suivant avec des classes abstraites:
MyStreamsClasses.java
/* File name : MyStreamsClasses.java */
import java.lang.*;
// Any number of import statements
public abstract class InputStream {
public void ReadObject(Object MyObject);
}
public abstract class OutputStream {
public void WriteObject(Object MyObject);
}
public abstract class InputOutputStream
imnplements InputStream, OutputStream {
public void DoSomethingElse();
}
peut être remplacé par:
Mystreaminterfaces.java
/* File name : MyStreamsInterfaces.java */
import java.lang.*;
// Any number of import statements
public interface InputStream {
public void ReadObject(Object MyObject);
}
public interface OutputStream {
public void WriteObject(Object MyObject);
}
public interface InputOutputStream
extends InputStream, OutputStream {
public void DoSomethingElse();
}
santé.
Q1. Comme les interfaces n'ont que des méthodes abstraites (pas de code), Comment Pouvons-nous dire que si nous implémentons une interface, alors c'est un héritage? Nous ne sommes pas à l'aide de son code.
ce n'est pas un héritage égal. C'est juste similaire. Laissez-moi vous expliquer:
VolvoV3 extends VolvoV2, and VolvoV2 extends Volvo (Class)
VolvoV3 extends VolvoV2, and VolvoV2 implements Volvo (Interface)
line1: Volvo v = new VolvoV2();
line2: Volvo v = new VolvoV3();
si vous ne voyez que les lignes 1 et 2, Vous pouvez en déduire que VolvoV2 et VolvoV3 ont le même type. Vous ne pouvez pas déduire si Volvo une superclasse ou Volvo est un interface.
Q2. Si implémenter une interface n'est pas un héritage, alors comment les interfaces sont-elles utilisées pour réaliser des héritages multiples?
utilisant maintenant des interfaces:
VolvoXC90 implements XCModel and Volvo (Interface)
VolvoXC95 implements XCModel and Volvo (Interface)
line1: Volvo a = new VolvoXC90();
line2: Volvo a = new VolvoXC95();
line3: XCModel a = new VolvoXC95();
si vous ne voyez que la ligne 1 et la ligne 2, Vous pouvez en déduire que VolvoXC90 et VolvoXC95 ont le même type (Volvo). Vous ne pouvez pas en déduire que Volvo est une superclasse ou Volvo est une interface.
si vous ne voyez que la ligne 2 et ligne 3 Vous pouvez en déduire que Volvo95 implémente deux types, XCModel et Volvo, en Java vous savez qu'au moins un doit être une interface. Si ce code était écrit en C++, par exemple, ils pourraient être les deux classes. Par conséquent, plusieurs héritages.
Q3. En tout cas, quel est l'avantage d'utiliser des Interfaces? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre.
Imaginez un système où vous utilisez une classe VolvoXC90 dans 200 autres classes.
VolvoXC90 v = new VolvoXC90();
si vous devez faire évoluer votre système pour lancer VolvoXC95, vous devez modifier 200 autres classes.
maintenant, imaginez un système où vous utilisez une interface Volvo dans 10.000.000 de classes.
// Create VolvoXC90 but now we need to create VolvoXC95
Volvo v = new VolvoFactory().newCurrentVolvoModel();
maintenant, si vous avez besoin d'évoluer votre système pour créer des modèles VolvoXC95, vous devez modifier une seule classe, L'usine.
c'est un bon sens question. Si votre système n'est composé que de quelques classes et a peu de mises à jour, les Interfaces d'utilisation sont contre-productives partout. Pour les grands systèmes, il peut vous épargner beaucoup de douleur et éviter le risque d'adopter des Interfaces.
je vous recommande de lire plus sur les principes S. O. L. I. D et de lire le livre Java efficace. Il a de bonnes leçons à tirer des ingénieurs logiciels expérimentés.
sont conçues de telle sorte qu'une classe implémente la fonctionnalité au sein de l'interface et se comporte conformément à cette interface.
vieille question. Je suis surpris que personne n'ait cité les sources canoniques: Java: an Overview par James Gosling, Design Patterns: Elements of Reusable Object-Oriented Software par The Gang of Four ou Effective Java par Joshua Bloch (entre autres sources).
je vais commencer par une citation:
Une interface est simplement une spécification d'un ensemble de méthodes auxquelles un objet répond. Il ne comprend pas de variables d'instance ou de mise en œuvre. Les Interfaces peuvent être multiplier héréditaire (contrairement aux classes) et ils peuvent être utilisés de façon plus flexible que la classe rigide structure de l'héritage. (Gosling,p. 8)
Maintenant, prenons vos suppositions et questions une par une (je vais volontairement ignorer les fonctionnalités de Java 8).
suppositions
Interface is collection de méthodes abstraites et de champs finaux.
avez-vous vu le mot-clé abstract
dans les interfaces Java? Aucun. Alors vous ne devriez pas considérer une interface comme une collection de méthodes abstraites. Peut-être que vous êtes induit en erreur par les soi-disant interfaces C++, qui sont des classes avec seulement des méthodes virtuelles pures. C++, de par sa conception, n'a pas (et n'a pas besoin d'avoir des interfaces, parce qu'il a plusieurs héritage.
comme expliqué par Gosling, vous devrait plutôt envisager une interface comme "un ensemble de méthodes d'un objet répond à". J'aime voir une interface et la documentation associée comme un contrat de service. Il décrit ce que vous pouvez attendre d'un objet qui implémente cette interface. La documentation doit spécifier les conditions préalables et postérieures (par exemple, les paramètres ne doivent pas être nuls, la sortie est toujours positive,...) et les invariants (une méthode qui ne modifie pas l'état interne de l'objet). Ce le contrat est le cœur, je pense, de L'OOP.
il n'y a pas d'héritage multiple en Java.
en effet.
JAVA omet de nombreuses fonctionnalités de C++ rarement utilisées, mal comprises et déroutantes qui, selon notre expérience, apportent plus de chagrin que de bénéfices. Il s'agit principalement de la surcharge de l'opérateur (bien qu'il y ait une surcharge de la méthode), de l'héritage multiple, et de nombreux coercions automatiques. (Gosling,p. 2)
rien à ajouter.
Les Interfacespeuvent être utilisées pour obtenir un héritage multiple en Java.
Non, simlpy parce qu'il n'y a pas d'héritage multiple en Java. Voir ci-dessus.
un point fort de L'héritage est que nous pouvons utiliser le code de la classe de base dans la classe dérivée sans l'écrire à nouveau. Peut-être que c'est la chose la plus importante pour l'héritage.
ça s'appelle "la mise en œuvre de l'héritage". Comme vous l'avez écrit, c'est un moyen pratique pour réutiliser le code.
mais il a une contrepartie importante:
les classes parentales définissent souvent au moins une partie de la représentation physique de leurs sous-classes. Parce que l'héritage expose une sous-classe aux détails de l'implémentation de son parent, on dit souvent que "l'héritage rompt l'encapsulation" [Sny86]. La mise en œuvre d'une sous-classe devient ainsi lié avec le mise en œuvre de sa classe mère que tout changement dans la mise en œuvre de la classe mère forcera la sous-classe à changer. (GOF, 1.6)
(il y a une citation similaire dans Bloch, point 16.)
en fait, l'héritage sert aussi un autre but:
classe héritage combine l'héritage d'interface et l'héritage de mise en œuvre. L'héritage d'Interface définit une nouvelle interface en termes d'un ou plus les interfaces existantes. L'héritage de mise en œuvre définit une nouvelle mise en œuvre en termes d'une ou plusieurs mises en œuvre existantes. (GOF, Annexe A)
utilisent tous les deux le mot clé extends
en Java. Vous pouvez avoir des hiérarchies de classes et des hiérarchies d'interfaces. Les premiers partagent la mise en œuvre, les seconds partagent les obligations.
Questions
Q1. Comme les interfaces n'ont que des méthodes abstraites (aucune code) alors comment pouvons-nous dire que si nous implémentons n'importe quelle interface alors c'est un héritage ? Nous ne sommes pas à l'aide de son code.**
L'implémentation d'une interface n'est pas un héritage. C'est la mise en œuvre. Ainsi le mot-clé implements
.
Q2. Si implémenter une interface n'est pas un héritage, alors comment les interfaces sont-elles utilisées pour obtenir un héritage multiple ?**
pas d'héritage multiple en Java. Voir ci-dessus.
Q3. En tout cas, quel est l'avantage d'utiliser des Interfaces ? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre./Alors pourquoi faire des interfaces ?Quels sont les avantages exacts de l'utilisation d'interfaces? Est-ce vraiment un héritage Multiple que nous réalisons en utilisant des Interfaces?
la question la plus importante est: pourquoi voudriez-vous avoir un héritage multiple? je peux penser à deux réponses: 1. pour donner mutliple types à un objet; 2. pour réutiliser le code.
donner des types multiples à un objet
En programmation orientée objet, un objet peut avoir les différents types de . Par exemple, en Java, un ArrayList<E>
a les types suivants: : Serializable
, Cloneable
, Iterable<E>
, Collection<E>
, List<E>
, RandomAccess
, AbstractList<E>
, AbstractCollection<E>
et Object
(j'espère que je n'ai oublié personne). Si un objet a différents types, différents consommateurs pourra l'utiliser sans être conscient de ses spécificités. J'ai besoin d'un Iterable<E>
et vous me donnez un ArrayList<E>
? C'est ok. Mais si j'ai besoin d'un List<E>
et que tu me donnes un ArrayList<E>
, c'est ok aussi. Etc.
comment dactylographier un objet dans OOP? Vous avez pris l'interface Runnable
comme exemple, et cet exemple est parfait pour illustrer la réponse à cette question. Je cite le Java doc officiel:
en outre, Runnable fournit les moyens pour une classe d'être active tout en ne subclassant pas le Thread.
voici le point: héritage est un moyen commode de Dactylographie objets. vous voulez créer un fil? Sous-classe la classe Thread
. Vous voulez qu'un objet ait des types différents, utilisons l'héritage multiple. Argh. Il n'existe pas en Java. (En C++, si vous voulez qu'un objet ait des types différents, multi-Heritage est le chemin à parcourir.)
comment donner des types mutliple à un objet alors? En Java, vous pouvez taper votre objet directement . C'est ce que vous faites quand votre classe implements
l'interface Runnable
. Pourquoi utiliser Runnable
si vous êtes un fan de l'héritage? Peut-être parce que votre classe est déjà une sous-classe d'une autre classe, disons A
. Maintenant votre classe A deux types: A
et Runnable
.
avec multiple les interfaces, vous pouvez donner plusieurs types à un objet. Vous avez juste à créer une classe qui implements
interfaces multiples. Tant que vous respectez les contrats, c'est ok.
code de réutilisation
c'est un sujet difficile; j'ai déjà cité le GOF sur briser l'encapsulation. Une autre réponse mentionnait le problème du diamant. On pourrait aussi penser au principe de la Responsabilité Unique:
A la classe doit avoir qu'une seule raison de changer. (Robert C. Martin, Agile de Développement de Logiciels, Principes, Modèles et Pratiques)
ayant une classe mère peut donner à une classe une raison de changer, outre ses propres responsabilités:
l'implémentation de la superclasse peut changer d'une version à l'autre, et si elle le fait, la sous-classe peut se casser, même si son code n'a pas été touché. En conséquence, un d'interfaces, puisque le javadoc est la seule chose dont j'ai besoin: un raccourci clavier dans L'IDE et je l'obtiens.
héritage howewer has advantages:
il est sûr d'utiliser l'héritage dans un paquet, où la sous-classe et les implémentations de la superclasse sont sous le contrôle des mêmes programmeurs. Il est également sûr d'utiliser l'héritage lors de l'extension de classes spécifiquement conçues et documentées pour l'extension (Point 17: conception et document de l'héritage ou de l'autre de l'interdire). (Bloch, point 16)
un exemple de classe" spécifiquement conçue et documentée pour l'extension "en Java est
AbstractList
.mais Bloch et GOF insistent sur ceci:" composition de faveur sur héritage":
la délégation est un moyen de rendre la composition aussi puissante pour la réutilisation que l'héritage [Lie86, JZ91]. En délégation, deux objets sont impliqués dans traitement d'une demande: un objet récepteur délègue des opérations à son délégué. Ceci est analogue aux sous-classes déférant des requêtes aux classes mères. (GOF p. 32)
Si vous utilisez la composition, vous n'aurez pas à écrire le même code encore et encore. vous créez juste une classe qui gère les duplications, et vous passez une instance de cette classe aux classes qui implémentent l'interface. C'est un moyen très simple de réutiliser du code. Et ce vous aide à suivre le principe de Responsabilité Unique et à rendre le code plus vérifiable. Rust et Go n'ont pas d'héritage (ils n'ont pas non plus de classes), mais je ne pense pas que le code soit plus redondant que dans d'autres langues OOP.
de plus, si vous utilisez la composition, vous vous trouverez naturellement en utilisant des interfaces pour donner à votre code la structure et la flexibilité dont il a besoin (voir d'autres réponses sur les cas d'utilisation d'interfaces).
Note: Vous pouvez partager du code avec des interfaces Java 8
et enfin, une dernière citation:
au cours de la mémorable séance de questions et réponses, Quelqu'un lui a demandé [James Gosling]: "si vous pouviez refaire Java, qu'est-ce que vous changeriez?""J'avais laisser de côté les classes" (n'importe où sur le net, je ne sais pas si c'est vrai)
Interfaces
une interface est un contrat définissant comment interagir avec un objet. Ils sont utiles pour exprimer votre internals l'intention d'interagir avec un objet. Après inversion de dépendance votre API publique aurait tous les paramètres exprimés avec des interfaces. Vous ne se soucient pas comment il fait ce que vous avez besoin de faire, c'est juste que c'est exactement ce dont vous avez besoin.
exemple: Vous pouvez tout simplement avoir besoin d'un Vehicle
pour transporter des marchandises, vous ne vous souciez pas du mode de transport particulier.
héritage
l'Héritage est une extension d'une implémentation particulière. Cette mise en œuvre peut satisfaire ou non une interface particulière. Vous devez vous attendre à un ancêtre d'une implémentation particulière seulement quand vous vous souciez du comment.
exemple: vous pouvez avoir besoin d'un Plane
mise en place d'un véhicule pour le transport rapide.
Composition
La Composition peut être utilisée comme alternative à l'héritage. Au lieu que votre classe étende une classe de base, elle est créée avec des objets qui implémentent de plus petites parties de la responsabilité de la classe principale. La Composition est utilisée dans les facade pattern
et decorator pattern
.
exemple: vous pouvez créer un DuckBoat
( DUKW ) classe qui met en œuvre LandVehicle
et WaterVehicle
qui tous deux mettent en œuvre Vehicle
composés de Truck
et Boat
mises en œuvre.
réponses
Les InterfacesQ1. Comme les interfaces n'ont que des méthodes abstraites (pas de code), Comment Pouvons-nous dire que si nous implémentons n'importe quelle interface alors c'est un héritage ? Nous ne sommes pas à l'aide de son code.
ne sont pas des héritages. Implémenter une interface exprime que vous avez l'intention que votre classe opère de la manière qui est définie par l'interface. L'héritage est quand vous avez un ancêtre commun, et vous recevez le même comportement ( inherit
) que l'ancêtre donc vous n'avez pas besoin de le définir.
Les InterfacesQ2. Si implémenter une interface n'est pas un héritage, alors comment les interfaces sont-elles utilisées pour obtenir un héritage multiple ?
ne sont pas obtenir un héritage multiple. Ils affirment qu'une classe peut convenir à plusieurs rôles.
Q3. En tout cas, quel est l'avantage d'utiliser des Interfaces ? Ils sont de ne pas avoir tout le code. Nous avons besoin d'écrire du code encore et encore dans toutes les classes que nous mettons en œuvre.
l'Un des principaux avantages des interfaces est de fournir à la séparation des préoccupations:
- Vous pouvez écrire une classe qui fait quelque chose avec une autre classe sans se soucier de la façon dont cette classe est mise en œuvre.
- tout développement futur peut être compatible avec votre mise en œuvre sans avoir besoin d'étendre une classe de base particulière.
dans l'esprit de DRY
vous pouvez écrire une implémentation qui satisfait une interface et la changer tout en respectant le open/closed principal
si vous utilisez la composition.