Bonsoir,
Je suis en train de faire un programme à propos d'un parking. Il y a deux type de place de parking(Particulier et Livraisons) et deux type de vehicule (voiture et camion). Les voitures peuvent se garer sur les deux type de place alors que les camions uniquement sur une place de livraisons. Mais j'ai un peu de mal à realiser cette condition. En effet, avant d'attribuer à vehicule à une place, j'aimerais tester si ce vehicule y est autorisé, mais je ne sais pas trop comment faire. Et je ne veux pas utilisé la methode instanceof().
J'avais pensé à rajouter un attribut aux classes Voiture et Camion du style "private String type" où je met "voiture" si je cree une voiture ou "camion" si je cree un camion. Mais je sais pas si c'est vraiment top top.
J'espère avoir été assez precis.
Merci
C'est "pire" que instanceof. Utilise la magie des interfaces et de la programmation objet. C'est fait exactement pour ça.
Comment on peut faire avec les interfaces ?
Car j'ai une classe abstraite Vehicule, une classe Voiture et Camion qui heritent tout deux de Vehicule, une classe abstraite Place, une classe Particulier et une classe Livraison qui heritent de Place. Mais je ne vois pas comment resoudre mon problème.
Tu peux utiliser la méthode .getClass()
Je crois
Tu connais le double dispatch ou le pattern visitor ? double dispatch en pseudo code
class Place
{
garer(Vehicule v)
{
// demande au véhicule d'appeler sa méthode correspondante
v.garer(this);
}
garerVoiture(Voiture v)
{
//...
}
garerCamion(Camion c)
{
//...
}
}
class Voiture
{
garer(Place p)
{
p.garerVoiture(this);
}
}
class Camion
{
garer(Place p)
{
p.garerCamion(this);
}
}
ainsi
Place p = new Livraison();
Vehicule va = new Voiture();
Vehicule vb = new Camion();
p.garer(va); // appelle va.garer() qui appelle p.garerVoiture()
p.garer(vb); // appelle vb.garer() qui appelle p.garerCamion()
Ah pas mal. Merci beaucoup
Desolé du double post mais j'ai une question. J'ai ces trois fonctions :
void garer(Vehicule V){...}
void garer(Voiture V){...}
void garer(Camion V){...}
Theoriquement, si je fais :
Vehicule V1 = new Voiture()
Vehicule V2 = new Camion()
V1.garer().
V2.garer()
Normalement, V1 appelle la deuxième methodes et V2 le troisième, non ?
elite_2009 faut laisser les personnes chercher, tu apprends mieux lorsque tu fais la démarche par toi-même, la preuve, il a des difficultés à comprendre un truc qui lui est servi clés en mains
K-Tastrophe La magie de ce système, c'est que c'est l'objet qui va dire à celui qui en a besoin que faire avec. Dans le cas présent, c'est la place qui demande à garer un véhicule comment se garer.
Interface Véhicule
méthode garer();
Classe Voiture implémente Véhicule
méthode garer(); vaut "Une voiture se gare sur une petite place"
Classe Camion implémente Véhicule
méthode garer(); vaut "Un camion se gare sur une grande place"
Classe Place
méthode garerVéhicule(Véhicule monVéhicule)
faire monVéhicule.garer();
Vehicule twingo = new Voiture();
Vehicule partner = new Camion();
Place unePlace = new Place();
unePlace.garer(partner);
unePlace.garer(twingo);
Ce qui offre l'avantage de ne pas avoir à intervenir sur la classe Place si tu implémente un nouveau Véhicule.
avec l'overloading, tu dois utiliser 2 interfaces, l'interface du visiteur et l'interface du visité.
interface GarerVisiteur {
garer(GareVisite gv);
garer(Voiture v);
garer(Camion c);
}
interface GareVisite {
garer(GarerVisiteur gv);
}
class Place implements GarerVisiteur {
garer(GareVisite gv) {
gv.garer(this);
}
}
class Voiture implements GareVisite {
garer(GarerVisiteur gv) {
gv.garer(this);
}
}
ainsi, le système de typage donne certaines garanties.
interface GarerVisiteur {
garer(GareVisite gv);
garer(Voiture v);
garer(Camion c);
}
C'est cette partie que je n'aime pas trop, ça crée un couplage fort dans le code.
Je suis daccord. Mais j'ai deux type de place. SI j'utilise ton code et que je fais :
Vehicule twingo = new Voiture();
Vehicule partner = new Camion();
Place unePetitePlace = new PetitePlace();
Place uneGrandePlace = new GrandePlace();
unePetitePlace.garer(partner);
uneGrandePlace.garer(partner);
Ca va me mettre le même resultat pour les deux garer(). Or justement, je ne veux pas que ca fasse la même chose. Mais si je fais :
unePetitePlace.garer(twingo)
uneGrandePlace.garer(twingo)
La je veux que ca fasse la même chose.
Non, tu as une interface "Place" et deux implémentations de celle-ci "GrandePlace" et "PetitePlace". C'est à la charge des véhicules de dire ce dont ils ont besoin, justement.
parking.garer(monVehicule)
monVehicule réclamera alors une place adaptée à son gabarit.
.class ça ne marche pas dans ce cas ?
Desolé mais je n'arrive toujours pas à comprendre comment faire . Au debut, j'avais ca :
interface Place {
public Vehicule garer(Vehicule V);
}
class PetitePlace{
private Vehicule vehiculegarer;
public Vehicule garerVehicule(Vehicule V){
this.vehiculegarer=V;
}
}
class GrandePlace{
private Vehicule vehiculegarer;
public Vehicule garerVehicule(Vehicule V){
this.vehiculegarer=V;
}
}
abstract class Vehicule{
private String immatriculation;
private String proprietaire;
}
class Voiture {
//Constructeur Voiture;
}
class Camion {
//Constructeur Camion;
}
Donc j'avais ca avant. Après, j'ai essayé comme vous m'avez dit de mettre une fonction garer dans les classes Voiture et Camion et d'appeller cette fonction dans la fonction garerVehicule. Mais je reviens toujours à mon problème : comment agir differement si j'appelle la fonction garer de vehicule dans la classe PetitePlace et dans la classe GrandePLace ?