CONNEXION
  • RetourJeux
    • Tests
    • Soluces
    • Previews
    • Sorties
    • Hit Parade
    • Les + attendus
    • Tous les Jeux
  • RetourActu
    • Culture Geek
    • Astuces
    • Réalité Virtuelle
    • Rétrogaming
    • Toutes les actus
  • RetourHigh-Tech
    • Actus JVTECH
    • Bons plans
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTECH
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch
    • Xbox Series
    • Overwatch 2
    • FUT 23
    • League of Legends
    • Genshin Impact
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • PS4
  • One
  • Switch
  • Wii U
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Etoile Abonnement RSS

Sujet : Qu'est-ce qu'une interface fait mieux qu'une classe abstraite concrètement ?

DébutPage précedente
1
Page suivantePage suivante
Darkai25 Darkai25
MP
Niveau 28
06 août 2022 à 21:40:32

Bonsoir !

Je suis relativement nouveau dans le milieu de la prog et je suis actuellement en train d'apprendre le Java. Forcément, au bout d'un moment on doit rentrer dans la Programmation orientée objet, et c'est souvent la que les choses se corsent pour les néophytes comme moi.

J'ai regardé une série de tutoriel jusqu'au point d'introduction sur les interfaces et les classes abstraites. J'ai globalement compris leurs utilités et leurs usages, mais j'ai du mal à comprendre dans quelle situation ce serait mieux d'implémenter une interface plutôt que d'étendre une classe abstraite ?

Je pense qu'avoir une réponse à cette question m'aiderait à mieux comprendre ce sujet avant de plonger plus bas dans la POO.

Merci d'avance !

Oberginee Oberginee
MP
Niveau 7
06 août 2022 à 22:09:51

Une classe abstraite est une classe, et une classe ne peut hériter d'une seule classe, peu importe elle est abstraite ou pas. En revanche, une classe peut hériter de plusieurs interfaces.

Ainsi, d'un point de vue de la conception, un héritage entre les classes est une relation de "is-a", c'est à dire une relation pour décrire le lien "être", toutefois, lors qu'on parle d'une classe qui hérite d'une interface, c'est plutôt une relation de "has-a", une composition ou bien une relation comportementale.

Ceci dit, il vaut mieux éviter l'utilisation des relations d'héritage mais privilégier les compositions (les "mixins"), car les derniers permettent d'une flexibilité à l'implémentation.

Un exemple: avec l'approche des classes, on peut dire qu'un chat est un animal, mais dans ce cas-là il est difficile de spécifier qu'il a combien de pieds, il a quelle couleur, etc.. En revanche, avec l'approche de l'interface, on peut très bien dire qu'un chat "fait partie des mammifères, fait partie des félins, fait partie des carnivores, des animaux domestiques, et cetera..."

Avant Java 8, les interfaces ne peuvent pas contenir des implémentations concrètes, à mon avis c'est la seule raison pour utiliser les classes abstraites. On est déjà à Java 18 et on peut mettre autant des implémentations qu'on veut dans une interface donc les classes abstraites ont peu d'intérêt.

Attention: ce point de vue est une idée dérivée qui est moins pointue de point de vue classique de POO donc si tu cherche une réponse au partiel de l'école ne met pas cet argument. Dans la POO purement académique et très pointue, la différence entre une classe abstraite et une interface c'est que la dernière ne peut pas contenir les implémentations.

Darkai25 Darkai25
MP
Niveau 28
06 août 2022 à 23:11:30

Le 06 août 2022 à 22:09:51 :
Une classe abstraite est une classe, et une classe ne peut hériter d'une seule classe, peu importe elle est abstraite ou pas. En revanche, une classe peut hériter de plusieurs interfaces.

Ainsi, d'un point de vue de la conception, un héritage entre les classes est une relation de "is-a", c'est à dire une relation pour décrire le lien "être", toutefois, lors qu'on parle d'une classe qui hérite d'une interface, c'est plutôt une relation de "has-a", une composition ou bien une relation comportementale.

Ceci dit, il vaut mieux éviter l'utilisation des relations d'héritage mais privilégier les compositions (les "mixins"), car les derniers permettent d'une flexibilité à l'implémentation.

Un exemple: avec l'approche des classes, on peut dire qu'un chat est un animal, mais dans ce cas-là il est difficile de spécifier qu'il a combien de pieds, il a quelle couleur, etc.. En revanche, avec l'approche de l'interface, on peut très bien dire qu'un chat "fait partie des mammifères, fait partie des félins, fait partie des carnivores, des animaux domestiques, et cetera..."

Avant Java 8, les interfaces ne peuvent pas contenir des implémentations concrètes, à mon avis c'est la seule raison pour utiliser les classes abstraites. On est déjà à Java 18 et on peut mettre autant des implémentations qu'on veut dans une interface donc les classes abstraites ont peu d'intérêt.

Attention: ce point de vue est une idée dérivée qui est moins pointue de point de vue classique de POO donc si tu cherche une réponse au partiel de l'école ne met pas cet argument. Dans la POO purement académique et très pointue, la différence entre une classe abstraite et une interface c'est que la dernière ne peut pas contenir les implémentations.

Merci beaucoup pour avoir pris le temps d'écrire cette réponse complète. :)

Pseudo supprimé
Niveau 9
07 août 2022 à 11:23:01

@Oberginee : Il faut arrêter d'utiliser les relations phylogéniques du règne animal pour illustrer la programmation orientée objet. [1]

Une interface c'est un type qui regroupe les objets qui vérifient un certain comportement.

Imaginons que tu codes un moteur d'expressions numériques. Un nombre est une expression, la somme de deux expressions est encore une expression. Une expression c'est quelque chose d'abstrait qu'on peut évaluer pour récupérer un nombre. On pourrait modéliser ça de la sorte.

interface Expr {
    evaluate(): int
}

class ConstantExpr implements Expr {
   constructor(int value) {
       this.value = value
   }
   evaluate(): int {
       return this.value
   }
}

class SumExpr implements Expr {
   constructor(Expr lhs, Expr rhs) {
      this.lhs = lhs
      this.rhs = rhs
   }
   evaluate(): int {
      return this.lhs.evaluate() + this.rhs.evaluate()
    }
}

Pour représenter le calcul 3+4+5 et calculer le résultat tu ferais comme suit.

expr = new SumExpr(
  new ConstantExpr(3),
  new SumExpr(
    new ConstantExpr(4),
    new ConstantExpr(5)
  )
)
print(expr.evaluate())

Ici, par définition une expression est quelque chose qu'on peut évaluer. Donc on définit l'interface Expr. Un objet de type Expr est un objet qu'on peut évaluer, un objet sur lequel on peut appliquer une méthode evaluate dont l'implémentation peut changer selon l'objet en question.

Maintenant, on a dit qu'une somme de deux expressions est elle-même une expression. Donc SumExpr prend en paramètre deux expressions et s'évalue comme la somme des évaluations de ces deux expressions.

Les classes abstraites c'est juste une généralisation des classes pour avoir un héritage plus général. Ta classe abstraite va implémenter certaines méthodes et laisser certaines autres virtuelles. En principe les méthodes implémentées vont reposer sur les méthodes virtuelles. Mais de façon générale l'héritage est plutôt une mauvaise pratique et donc les classes abstraites aussi. Tu vas utiliser ça dans des situations vraiment très précises où tu veux absolument utiliser de l'héritage pour une raison ou une autre.

En résumé : une interface c'est un type, ça permet de travailler avec des objets qui peuvent être très différents les uns des autres mais sur lesquels on peut opérer d'une certaine façon. Une classe abstraite ça généralise les classes dans le cadre de l'héritage et ça permet de partager du code.

[1] https://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/

Pseudo supprimé
Niveau 9
07 août 2022 à 11:36:25

Une classe abstraite est une classe, et une classe ne peut hériter d'une seule classe, peu importe elle est abstraite ou pas. En revanche, une classe peut hériter de plusieurs interfaces.

À noter quand même que c'est une différence parfaitement superficielle et spécifique à Java. On peut très bien concevoir un langage qui permet l'héritage multiple, le problème du diamant est résolu depuis bien longtemps. D'ailleurs c'est le cas du C++.

Message édité le 07 août 2022 à 11:36:36 par
godrik godrik
MP
Niveau 22
08 août 2022 à 01:53:15

@binecointe,

Tu parles souvent de la mauvaise utilisation de l'heritage/polymorphisme. Et tu donnes des liens a des blogs comme celui que tu as mis ici. Tu connais une bonne ressource plus completes qu'on pourrait donner aux debuttants?

Pseudo supprimé
Niveau 9
08 août 2022 à 10:40:16

Le 08 août 2022 à 01:53:15 :
@binecointe,

Tu parles souvent de la mauvaise utilisation de l'heritage/polymorphisme. Et tu donnes des liens a des blogs comme celui que tu as mis ici. Tu connais une bonne ressource plus completes qu'on pourrait donner aux debuttants?

J'ai pas mieux sous la main malheureusement. Faudrait chercher du côté des livres sur la programmation orientée objet d'un point de vue théorique. J'ai pas vraiment le temps de m'y consacrer.

godrik godrik
MP
Niveau 22
08 août 2022 à 14:48:37

Pas de soucis!

DébutPage précedente
1
Page suivantePage suivante
Répondre
Prévisu
?
Victime de harcèlement en ligne : comment réagir ?
Infos 0 connecté(s)

Gestion du forum

Modérateurs : godrik, LGV
Contacter les modérateurs - Règles du forum

Sujets à ne pas manquer

La vidéo du moment