8
votes

Pourquoi faire des classes et des interfaces abstraites?

Eh bien, j'allais demander quelle est la différence, mais cela a été répondu auparavant. Mais maintenant, je demande pourquoi ont-ils fait ces différences? (Je parle de Java ici, je ne sais pas si la même chose s'applique à d'autres langues)

Les deux choses semblent très similaires. Les classes abstraites peuvent définir un corps de méthode tandis que les interfaces ne peuvent pas, mais plusieurs interfaces peuvent être héritées. Alors, pourquoi n'a-t-il pas (par «ils», je veux dire au soleil quand ils ont écrit Java) Faites une chose où vous pouvez écrire un corps de méthode et Ce type peut être hérité plus d'une fois par une classe. < / p>

Y a-t-il un avantage pour ne pas être capable d'écrire un corps de méthode ou de s'étendre plusieurs fois que je ne vois pas?


0 commentaires

7 Réponses :


3
votes

Plus de héritage est plus difficile à mettre en œuvre dans une langue (compilateur vraiment) car cela peut entraîner certaines questions. Ces problèmes ont été discutés ici avant: Quel est le problème exact avec plusieurs héritage .

J'ai toujours supposé que c'était un compromis en Java. Les interfaces permettent à une classe de remplir plusieurs contrats sans maux de tête de multiples héritage.


0 commentaires

0
votes

L'autre approche que vous décrivez est l'approche utilisée par C ++ (mélanges par exemple). Les problèmes liés à un tel "héritage multiple" sont assez complexes et comptent plusieurs critiques en C ++.


5 commentaires

C ++ n'a pas de mélanges comme je les comprends. Les mélanges peuvent être ajoutés à une classe à l'exécution ("Ajouter un comportement de l'enregistreur à cette instance DBI"), qui n'est pas une partie centrale de la langue C ++.


@Philip je ne sais pas ce que tu veux dire. Les mélanges sont souvent utilisées en C ++, peut-être la plus connue dans les livres de Grady Booch.


Je pense que nous ne sommes tout simplement pas d'accord sur la définition de "mixin" alors. Pas de gros problème, bouge.


@Philip j'ai recherché "Mélangements d'exécution" et maintenant je comprends ce que vous voulez dire. Les langues dynamiques sont la hanche et je semble être en retard à cet égard.


Pour être honnête, mon expérience de mixines est limitée au Moose de Perl :: Rôle S, qui n'est pas tout à fait la même chose. Nous avons plus de concepts disponibles que nous n'avons des mots pour les décrire ces jours-ci.



10
votes

Parce que permettant aux classes d'hériter de multiples implémentations pour la même méthode signature conduit à la question évidente, laquelle devrait être utilisée au moment de l'exécution.

Java évite ceci en soutenant plusieurs héritages uniquement pour les interfaces. Les signatures déclarées dans chaque interface peuvent être combinées beaucoup plus facilement (Java utilise essentiellement l'Union de toutes les méthodes)


1 commentaires

Ah, je savais qu'il y ait quelque chose qui me manquait, c'est un sens!



5
votes

Héritage multiple en C ++ conduit à des ambiguïtés sémantiques comme le Problème de héritage de diamant . MI est assez puissant, mais a des conséquences complexes.

Faire des interfaces Un cas spécial augmente également la visibilité du concept comme moyen d'informations cacher et réduire la complexité du programme. En C ++, la définition des bases abstraites pures est un signe d'un programmeur mature. En Java, vous les rencontrez à une étape beaucoup plus précoce de l'évolution d'un programmeur.


0 commentaires

1
votes

Les faire une chose est la voie que les gars Scala ont pris avec des traits qui est une interface pouvant avoir des méthodes et prend en charge plusieurs héritages.

Je pense que les interfaces, pour moi, sont propres en ce sens qu'elles spécifient uniquement les exigences (conception par contrat), tandis que les classes abstraites définissent un comportement commun (mise en œuvre), donc un outil différent pour un travail différent? Les interfaces permettent probablement une génération de code plus efficace pendant le temps de compilation également?


0 commentaires

0
votes

Héritage signifie que vous héritez de la nature (sens) et responsabilité (comportement) de la classe mère, tandis que la mise en œuvre de l'interface signifie que vous remplissez un contrat (par exemple, sérialisable), qui peut avoir rien à voir avec la nature principale ou la responsabilité de la classe.

Classe abstraite Vous permet de définir une nature que vous souhaitez être générique et non instanciable, car elle doit être spécialisée. Vous savez comment effectuer certaines tâches de haut niveau (par exemple, prendre une décision selon certains paramètres), mais vous ne connaissez pas les détails de certaines actions de niveau inférieur (par exemple, calculez certains paramètres intermédiaires), car cela dépend des choix de mise en œuvre. Une alternative à la résolution de ce problème est le modèle de conception de stratégie . Il est plus flexible, permettant ainsi une commutation de stratégie d'exécution et un comportement nul, mais il est plus complexe (et le swtiching d'exécution n'est pas toujours nécessaire). De plus, vous risquez de perdre des Signification et des installations de dactylographie (polymorphisme et vérification de type devient un peu plus difficile car la stratégie est un composant, pas l'objet lui-même).

résumé class = est-a, stratégie = a-a

éditer: comme pour plusieurs héritage, voir la réponse de Pontus Gagge.


0 commentaires

2
votes

Considérez cet exemple:

public abstract class Engine
{
  public abstract void switchPowerOn();
  public abstract void sprinkleSomeFuel();
  public abstract void ignite();

  public final void start()
  {
    switchPowerOn();
    sprinkleSomeFuel();
    ignite();
  }
}


0 commentaires