Menu

Pb : Classe abstraite vs Classe instanciable

Messages postés
1
Date d'inscription
lundi 11 mars 2019
Dernière intervention
11 mars 2019
- - Dernière réponse : Whismeril
Messages postés
12932
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
23 mars 2019
- 11 mars 2019 à 19:29
Bonjour,
Je cherche à résoudre un pb de ce type :
Classes principales :

- Animal : une classe mère
- Les sous classes d'Animal : Chien/ Chat / Lapin / etc...
- Une classe animaux_par_Region contenant entre autres la liste des animaux présent dans une région : {chien, chat, lapin...}

D'après mes recherches sur internet, il faudrait que Animal soit une classe abstraite afin de créer des méthodes abstraites reprises et adaptées par chacun des animaux (ex: crier() pour un chien renverrait "Le chien aboie", ou "Le chat miaule" pour un chat).
Cependant, dans ma mainClasse, j'aimerais parcourir une liste animaux_par_Region (liste de chiens/chats/lapins...)

PB : je ne peux pas instancier cette liste par une liste d'objets Animal étant donné que la classe Animal est abstraite... Et je ne sais pas du tout à l'avance quelles sous classes rempliront la liste animaux_par_Region.
De plus, quand bien même je n'utiliserais pas Animal comme une classe abstraite, je n'arrive pas à parcourir une liste animaux_par_Region sans perdre l'information sur la sous classe.

Voici un exemple de ce que je souhaite pouvoir faire :

animal_par_Region region = new animal_par_Region({chat, chien});
for (Animal animal : region)//Parcours une liste d'animaux par région
system.out.println(animal.crie() ); //renvoi le cri de l'animal en question

Dans l'idéal, renverrai "Le chat miaule" \n "Le chien aboie"

Merci d'avance

Configuration: Windows / Firefox 65.0
Afficher la suite 

Votre réponse

2 réponses

Messages postés
12932
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
23 mars 2019
499
0
Merci
Bonjour

je ne code pas en Java, donc je ne vais parler que de principes généraux et pas de leurs applications dans ce langage.
Si quelqu'un t'avais répondu, je me serais abstenu, mais faut croire qu'il n'y a personne aujourd'hui.

Le principe du polymorphisme est qu'un objet est du type avec lequel il a été défini, mais aussi de tous les types dont il hérite.

On pourrait imaginer que tu as la classe abstraite Animal, en classes mères tu as les classes abstraites Mammifère, Reptile, Oiseau, Poisson, etc.... Dérivant de Mammifère et toujours abstrait tu pourrais avoir Ovin, Bovin, Equin, Canide etc... et enfin dérivant de Canide tu aurais, Chien, Loup etc...

Et bien un Chien, est aussi un Canide, un Mamifère et un Animal.
Et cela "marche" dans l'autre sens, c'est à dire qu'un Chien, un Loup, une Carpe, un Oie et un Lézard sont tous des Animaux.

Donc dans une collection d'Animaux, tu peux les ranger par région.
Pour accéder aux membres communs y'a pas de soucis
Animaux[i].Crier();
retournera
"Le chien aboie"
si l'item i de la collection est un chien, et
"bloup bloup"
si c'est une carpe.

Et pour utiliser un membre spécifique au type, il faut caster l'instance dans le type final.
En C# ça donnerait
if(Animaux[i] is Chien)//on détermine si l'item i est un chien
{
     ((Chien)Animaux[i]).MarquerTerritoire(); //si c'est le cas on caste pour utiliser la méthode spécifique
}

Java est C# sont assez proche. Non seulement je suis certain qu'on peut faire la même chose en Java, mais si ça se trouve c'est la même syntaxe.

Commenter la réponse de Whismeril
Messages postés
15954
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
18 mars 2019
3537
0
Merci
Bonjour,

PB : je ne peux pas instancier cette liste par une liste d'objets Animal étant donné que la classe Animal est abstraite...
Si tu peux tout à fait, on appelle ça le polymorphisme :

List<Animal> animaux = Arrays.asList(chat, chien);

"je n'arrive pas à parcourir une liste animaux_par_Region sans perdre l'information sur la sous classe"
Tu peux créer une méthode dans la classe Animal qui te renvoie de quelle espèce est chaque animal :

for (Animal animal : animaux) {
    System.out.println("Le " + animal.espece() + " " + animal.cri());
}

Remarque : d'un point de vue purement mécanique on peut aussi utiliser la méthode getClass de Object
Whismeril
Messages postés
12932
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
23 mars 2019
499 -
Salut kx, et caster comme je l’ai proposé est il bien possible en java?
KX
Messages postés
15954
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
18 mars 2019
3537 > Whismeril
Messages postés
12932
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
23 mars 2019
-
Oups, je n'avais pas vu ta réponse, ça a du se croiser...

En Java tu peux bien sûr faire pareil :

if (animaux[i] instanceof Chien) {
    ((Chien) animaux[i]).marquerTerritoire();
}
Whismeril
Messages postés
12932
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
23 mars 2019
499 -
Au moins j'ai pas dit de connerie ;), bonne soirée
Commenter la réponse de KX