Je suis un débutant en programmation Java, j'essaie de comprendre la POO.
J'ai donc construit cette classe abstraite:
public abstract class Véhicule{....}
et 2 sous-classes:
public class Voiture extends Véhicule{....}
public class Bateau extends Véhicule{....}
Voiture
et Bateau
ont également des champs et des méthodes uniques qui ne sont pas communs (n'ont pas le même nom, je ne peux donc pas définir de méthode abstraite pour eux dans Véhicule).
Maintenant dans mainClass, j'ai configuré mon nouveau Garage:
Véhicule[] monGarage = new Véhicule[10];
monGarage[0]=new Voiture(2,true);
monGarage[1]=new Bateau(4,600);
J'étais très content du polymorphisme jusqu'à ce que j'essaie d'accéder à l'un des champs qui sont uniques à la Voiture, comme par exemple:
boolean voitureEstAutomatique = monGarage[0].auto;
Le compilateur n'accepte pas cela. J'ai contourné ce problème en utilisant la conversion:
boolean voitureEstAutomatique = ((Voiture)monGarage[0]).auto;
Cela fonctionne... mais cela n'aide pas avec les méthodes, seulement avec les champs. Cela signifie que je ne peux pas faire
((Voiture)monGarage[0]).faireQuelqueChose();
Alors ma question est - qu'est-ce que j'ai vraiment dans mon garage? J'essaie d'avoir l'intuition ainsi que de comprendre ce qui se passe "en coulisses".
pour l'intérêt des futurs lecteurs, un bref résumé des réponses ci-dessous:
- Oui, il y a une
Voiture
dansmonGarage[]
- Étant donné que Java est un langage à typage statique, le compilateur Java n'autorisera pas l'accès aux méthodes/champs qui ne sont pas de type "Véhicule", si on y accède à travers une structure de données basée sur la super classe Véhicule (comme
Véhicule monGarage[]
) - Quant à la façon de résoudre le problème, il y a 2 approches principales ci-dessous:
- Utiliser la conversion de type, ce qui rassurera les préoccupations du compilateur et laissera d'éventuelles erreurs de conception à l'exécution
- Le fait que j'ai besoin d'une conversion indique que la conception est défectueuse. Si j'ai besoin d'accéder à des capacités non liées à Véhicule, je ne devrais pas stocker les Voitures et Bateaux dans une structure de données basée sur Véhicule. Soit faire appartenir toutes ces capacités à Véhicule, soit utiliser des structures basées sur des types plus spécifiques (dériver)
- Dans de nombreux cas, la composition et/ou les interfaces seraient une meilleure alternative à l'héritage. Probablement le sujet de ma prochaine question...
- Et encore de nombreux autres bons aperçus ci-dessous, si on a le temps de parcourir les réponses.