OVH Cloud OVH Cloud

[Débutante] Construction d'un objet

30 réponses
Avatar
Lea
Bonjour,

Que fait-on avec l'instruction suivante :
A o1=new B();

Merci.

Léa

10 réponses

1 2 3
Avatar
Lea
Lea wrote:


Je suis pas sûre de tout avoir compris :



Je ne suis pas connu pour ma grande pédagogie... ;)

la référence o1 construite avec les données, constructeurs et méthodes
de la classe B "se situe" dans la classe A ou B?



*Exemple* :

<code>

public interface A {
public void uneMethode();
}

public class B implements A {
public B() {
//...
}
public void uneMethode() {
//...
}
public void uneAutreMethode() {
//...
}
}

public class Main {
public static void main(String[] args) {
A r1 = new B();
r1.uneMethode(); // OK.
r1.uneAutreMethode(); // ERREUR!
}
}

</code>


A r1 = new B();
-->on crée une référence r1 de type A (donc "pilotable à partir de A")
ayant les méthodes de B?
r1.uneMethode();
-->renvoie à la méthode de la classe A, non?
-->puisque pilotable à partir de A et méthode de la même classe, pas
d'erreur?
r1.uneAutreMethode();
-->renvoie à la méthode de la classe B, non?
-->puisque pilotable à partir de A et méthode d'une autre classe, erreur?

Il est possible que je sois complétement à côté de la plaque mais c'est
vraiment pas évident à comprendre ...



*Remarque* :

J'utilise /r1/ et non /o1/ pour bien souligner que ce n'est pas un objet
mais une référence. Attention, dans la pratique, nous avons tendance à
interchanger ces termes. En java, il y a des identifiants pour les
référence (/r1/), les méthodes (/uneMethode/), les classes (/B/), les
types primitifs, etc., mais il n'y en a pas pour les objets !


Valdo.



Avatar
Wismerhill
Lea ecrivit le 25/02/2005 13:58 :

Le fait que la classe concrète de la partie droite soit équivalente au
type de la partie gauche n'implique rien de particulier pour la suite.



Mais alors pourquoi se donner la peine de l'écrire sous la forme A
o2=new B();


c.f. séparation interface/implémentation. Chercher (google) aussi
programmation par contrat (design by contract).


Avatar
Wismerhill
Lea ecrivit le 25/02/2005 14:25 :

Lea wrote:


Je suis pas sûre de tout avoir compris :




Je ne suis pas connu pour ma grande pédagogie... ;)

la référence o1 construite avec les données, constructeurs et
méthodes de la classe B "se situe" dans la classe A ou B?




*Exemple* :

<code>

public interface A {
public void uneMethode();
}

public class B implements A {
public B() {
//...
}
public void uneMethode() {
//...
}
public void uneAutreMethode() {
//...
}
}

public class Main {
public static void main(String[] args) {
A r1 = new B();
r1.uneMethode(); // OK.
r1.uneAutreMethode(); // ERREUR!
}
}

</code>



A r1 = new B();
-->on crée une référence r1 de type A (donc "pilotable à partir de A")
ayant les méthodes de B?
r1.uneMethode();


Pas exactement, tu crées une référence sur un type A, mais tu lui
affectes une instance de type B, ce qui est possible car B hérite de A
(B est aussi A).

-->renvoie à la méthode de la classe A, non?
-->puisque pilotable à partir de A et méthode de la même classe, pas
d'erreur?
r1.uneAutreMethode();


OK

-->renvoie à la méthode de la classe B, non?
-->puisque pilotable à partir de A et méthode d'une autre classe, erreur?


Erreur de compilation car le type A n'a pas cette méthode.

Il y a un concept fondamentale en java à comprendre le plus tôt
possible et qui n'est pas forcément évident. L'édition de lien est
statique. Ca signifie que le choix de la signature de la méthode à
appeler est déterminé à la compilation. Par contre, le choix de
l'implémentation de la méthode est dynamique, c'est à dire déterminé à
l'exécution (ce qui permet de le polymorphisme).

Dans l'exemple, tu appelles uneAutreMethode(), sur une référence de
type A (soit ri). Le compilo va chercher si la classe A possède une
signature de méthode correspondante (ce qui n'est pas le cas -> erreur
de compile) et ce alors même que tu sais, toi, qu'à l'exécution ri
pointera bien sur une instance de B, qui possède cette signature de
méthode.



Avatar
Valdo Tschantre
ZebX wrote:
Ton approche de l'objet (en dehors de Java proprement dit) m'interresse.
As tu un livre en francais à me conseiller sur le sujet ?


*Un Messie : /Grady Booch/*
Le premier livre que j'ai lu sur les modèles orientés objets est, si je
me souviens bien du titre : *Analyse et conception orientée objet* de
Grady Booch (http://fr.wikipedia.org/wiki/Grady_Booch). Il s'agissait
de sa second édition et nous étions alors en 1997. Je ne sais pas si il
a été réédité depuis... Quoi qu'il en soit, c'est ce livre qui a forger
mon approche de l'orienté objet (même si alors, j'étais encore loin d'en
comprendre toute les implications). De ses 400 pages, une formule ma
notamment marquée : "*Objet = Identité + Interface + Comportement*", (à
méditer...); ainsi qu'un principe : *Deux objets communiquent entre eux
via des messages* - et non pas par appel de méthode (à méditer
également...).

*Une bible : /Design Patterns/*
Le second livre - que tu trouvera dans toutes les bonnes librairies -
est : *Design Patterns* (/Catalogue de modèles de conception
réutilisables/) de Eric Gamma, Richerd Helm, Ralph Johnson et John
Vlissides. Ce livre apporte à mon sens deux choses :
- Une bonne utilisation des concepts utilisé dans les modèles orientés
objets - notamment des principes tel que : "*Programmer pour une
interface, non pour un développement*" ou "*Préférer la composition
d'objets à l'héritage de classes*".
- Un langage pour tous les concepteurs et développeurs... et il y aurait
beaucoup à dire à ce sujet.

*Et Java...*
Quoi que ce langage - comme tous les autres langages - propose sa propre
approche des modèles orientés objets, ses concepts simples de pakages et
d'interfaces nous fournissent à eux seuls (moyennant quelques
commentaires bien sentit, gérés par la JavaDoc) un véritable langage de
spécification : "*De la sémantique, rien que de la sémantique... pour
la forme on verra après.*" (et ça, c'est de moi ;) ).


Je conclurais en disant qu'il existe finalement plusieurs modèles
orientés objets. Je m'efforce seulement de ME définir celui que je
manipulerais le plus facilement... sans perdre en pragmatisme (les
règles sont faites par-ce que l'on peut les détourner... ;) )


Valdo.


--


Avatar
ZebX

*Un Messie : /Grady Booch/*

*Une bible : /Design Patterns/*


Merci de tes conseils.

Avatar
jerome moliere
Lea wrote:


Lea wrote:


Je suis pas sûre de tout avoir compris :




Je ne suis pas connu pour ma grande pédagogie... ;)

la référence o1 construite avec les données, constructeurs et
méthodes de la classe B "se situe" dans la classe A ou B?




*Exemple* :

<code>

public interface A {
public void uneMethode();
}

public class B implements A {
public B() {
//...
}
public void uneMethode() {
//...
}
public void uneAutreMethode() {
//...
}
}

public class Main {
public static void main(String[] args) {
A r1 = new B();
r1.uneMethode(); // OK.
r1.uneAutreMethode(); // ERREUR!
}
}

</code>



A r1 = new B();
-->on crée une référence r1 de type A (donc "pilotable à partir de A")
ayant les méthodes de B?
r1.uneMethode();
-->renvoie à la méthode de la classe A, non?
-->puisque pilotable à partir de A et méthode de la même classe, pas
d'erreur?
r1.uneAutreMethode();
-->renvoie à la méthode de la classe B, non?
-->puisque pilotable à partir de A et méthode d'une autre classe, erreur?

Il est possible que je sois complétement à côté de la plaque mais c'est
vraiment pas évident à comprendre ...
allez oups je vais tenter l'aventure et je vais m'appuyer sur un exemple...

tu veux modeliser un zoo, dans lequel il y a des animaux (pas etonnant
:) )..
Un animal au sens generique va avoir un certain de nombre de
caracteristiques:
temperature, alimentration, savoir crier/sauter etc...

Soit une classe mere Animal
Deux classes filles Lion et Gazelle
classes filles implique relation du type 'est un' ou is a en anglais
Un lion est un animal....
maintenant tu es directeur du zoo et tu veux faire l'appel de tes
troupes (savoir sd'il n'en manque pas)
tu vas donc faire sur toute ta liste d'animaux:
animaux[i].crier()
ou animaux est un tableaux rempli d'animaux !!!
donc de Animal!!!
Animal[] animaux= new Animaux[2]; // 2 animaux dans mon zoo
animaux[0]=new Lion("totor"); // le lion s'appelle totor
animaux[1]= new Gazelle("esmeralda");// la gazelle esmeralda!!!
tu decris un tableau dont le type statique est Animal mais dont les
instances seront de type dynamique Lion ou Gazelle
ainsi lors de l'appel tu auras des "GRRRR" ou des "HianHian" (une
gazelle fait hian hian c'est connu!!)

tu constates alors que l'on a des A a = new B(); comme dans ta question...
on ne manipulera quer les services definis dans l'interface (classe
mere) avec des pecialisations (B ou C Gazelle et Lion dans mon exemple)
HTH
Jerome

--
Auteur cahier du programmeur Java tome 2 - Eyrolles 10/2003
http://www.eyrolles.com/php.informatique/Ouvrages/ouvrage.php3?ouv_ean13—82212111941



Avatar
Lea

Pourquoi o2 ne peut accéder à la couleur?


Parce que o2 "croit" qu'il référence une instance de A et non de B. Or A
n'a pas de couleur.
Si tu complètes par o3 = o2; tu peux alors accéder à la couleur de o2
via la référence o3.
Si tu fais o2 = o3, le compilateur te jette car o2 n'a pas la capacité
de représenter une référence sur B ;

Maintenant dans la pratique, c'est util pour simplifier l'usage de ton code.

Tu crées la classe GestionRessourcesHumaines :) et tu donnes une
interface (vue limitée) IComptable au comptable, IProjet au chef de
projet et IEmbauche au recruteur...

Chacun ne voit que la partie qui le concerne :
plus simple à produire -tu peux morcellé ton dev
plus simple à utiliser - l'interface est ton "seul engagement" vis à vis
des utilisateurs de ta classe.
et moins d'effet de bord dans la vie du produit par rapport à une
application mainframe par exemple :)


Je crois avoir compris mais bon c'est à toi de me le dire.
Si on prends l'exemple :

class ciel{
private int a;
public int b;
protected int d;
...

class nuage extends ciel{
private int e;
public int f;
protected int g;
...

A o1=new A();
B o2=new B();
A o3=new B();

o3.a // erreur compil car a est private ?
o3.b // acces à b possible car reference o3 est de type A et b public ?
o3.c // acces à c possible car reference o3 est de type A, c protected
et appel par classe externe mais ttes les classes sont dans le même
répertoire ?
o3.e // erreur compil car reference o3 est de type A et non de B ?
o3.f et o3.g // mm chose


Avatar
Lea
Lea ecrivit le 25/02/2005 14:25 :


Lea wrote:


Je suis pas sûre de tout avoir compris :





Je ne suis pas connu pour ma grande pédagogie... ;)

la référence o1 construite avec les données, constructeurs et
méthodes de la classe B "se situe" dans la classe A ou B?





*Exemple* :

<code>

public interface A {
public void uneMethode();
}

public class B implements A {
public B() {
//...
}
public void uneMethode() {
//...
}
public void uneAutreMethode() {
//...
}
}

public class Main {
public static void main(String[] args) {
A r1 = new B();
r1.uneMethode(); // OK.
r1.uneAutreMethode(); // ERREUR!
}
}

</code>




A r1 = new B();
-->on crée une référence r1 de type A (donc "pilotable à partir de A")
ayant les méthodes de B?
r1.uneMethode();



Pas exactement, tu crées une référence sur un type A, mais tu lui
affectes une instance de type B, ce qui est possible car B hérite de A
(B est aussi A).

-->renvoie à la méthode de la classe A, non?
-->puisque pilotable à partir de A et méthode de la même classe, pas
d'erreur?
r1.uneAutreMethode();



OK

-->renvoie à la méthode de la classe B, non?
-->puisque pilotable à partir de A et méthode d'une autre classe,
erreur?



Erreur de compilation car le type A n'a pas cette méthode.

Il y a un concept fondamentale en java à comprendre le plus tôt possible
et qui n'est pas forcément évident. L'édition de lien est statique. Ca
signifie que le choix de la signature de la méthode à appeler est
déterminé à la compilation.


Que veut dire "signature" ?

Par contre, le choix de l'implémentation de la méthode est dynamique,
c'est à dire déterminé à l'exécution (ce qui
permet de le polymorphisme).

Dans l'exemple, tu appelles uneAutreMethode(), sur une référence de type
A (soit ri). Le compilo va chercher si la classe A possède une signature
de méthode correspondante


quelle est-elle dans cet exemple?
(ce qui n'est pas le cas -> erreur de compile)
et ce alors même que tu sais, toi, qu'à l'exécution ri pointera bien sur
une instance de B, qui possède cette signature de méthode.


Dans cet exemple qu'est ce qui permet de dire que l'implémentation de la
méthode est dynamique?

Merci




Avatar
Lea
Lea ecrivit le 25/02/2005 14:25 :


Lea wrote:


Je suis pas sûre de tout avoir compris :





Je ne suis pas connu pour ma grande pédagogie... ;)

la référence o1 construite avec les données, constructeurs et
méthodes de la classe B "se situe" dans la classe A ou B?





*Exemple* :

<code>

public interface A {
public void uneMethode();
}

public class B implements A {
public B() {
//...
}
public void uneMethode() {
//...
}
public void uneAutreMethode() {
//...
}
}

public class Main {
public static void main(String[] args) {
A r1 = new B();
r1.uneMethode(); // OK.
r1.uneAutreMethode(); // ERREUR!
}
}

</code>




A r1 = new B();
-->on crée une référence r1 de type A (donc "pilotable à partir de A")
ayant les méthodes de B?
r1.uneMethode();



Pas exactement, tu crées une référence sur un type A, mais tu lui
affectes une instance de type B, ce qui est possible car B hérite de A
(B est aussi A).

-->renvoie à la méthode de la classe A, non?
-->puisque pilotable à partir de A et méthode de la même classe, pas
d'erreur?
r1.uneAutreMethode();



OK

-->renvoie à la méthode de la classe B, non?
-->puisque pilotable à partir de A et méthode d'une autre classe,
erreur?



Erreur de compilation car le type A n'a pas cette méthode.

Il y a un concept fondamentale en java à comprendre le plus tôt possible
et qui n'est pas forcément évident. L'édition de lien est statique. Ca
signifie que le choix de la signature de la méthode à appeler est
déterminé à la compilation.


Que veut dire "signature" ?

Par contre, le choix de l'implémentation de la méthode est dynamique,
c'est à dire déterminé à l'exécution (ce qui
permet de le polymorphisme).

Dans l'exemple, tu appelles uneAutreMethode(), sur une référence de type
A (soit ri). Le compilo va chercher si la classe A possède une signature
de méthode correspondante


quelle est-elle dans cet exemple?
(ce qui n'est pas le cas -> erreur de compile)
et ce alors même que tu sais, toi, qu'à l'exécution ri pointera bien sur
une instance de B, qui possède cette signature de méthode.


Dans cet exemple qu'est ce qui permet de dire que l'implémentation de la
méthode est dynamique?

Merci




Avatar
Wismerhill
Lea ecrivit le 27/02/2005 22:22 :

Lea ecrivit le 25/02/2005 14:25 :


Lea wrote:


Je suis pas sûre de tout avoir compris :






Je ne suis pas connu pour ma grande pédagogie... ;)

la référence o1 construite avec les données, constructeurs et
méthodes de la classe B "se situe" dans la classe A ou B?






*Exemple* :

<code>

public interface A {
public void uneMethode();
}

public class B implements A {
public B() {
//...
}
public void uneMethode() {
//...
}
public void uneAutreMethode() {
//...
}
}

public class Main {
public static void main(String[] args) {
A r1 = new B();
r1.uneMethode(); // OK.
r1.uneAutreMethode(); // ERREUR!
}
}

</code>





A r1 = new B();
-->on crée une référence r1 de type A (donc "pilotable à partir de
A") ayant les méthodes de B?
r1.uneMethode();




Pas exactement, tu crées une référence sur un type A, mais tu lui
affectes une instance de type B, ce qui est possible car B hérite de A
(B est aussi A).

-->renvoie à la méthode de la classe A, non?
-->puisque pilotable à partir de A et méthode de la même classe, pas
d'erreur?
r1.uneAutreMethode();




OK

-->renvoie à la méthode de la classe B, non?
-->puisque pilotable à partir de A et méthode d'une autre classe,
erreur?




Erreur de compilation car le type A n'a pas cette méthode.

Il y a un concept fondamentale en java à comprendre le plus tôt
possible et qui n'est pas forcément évident. L'édition de lien est
statique. Ca signifie que le choix de la signature de la méthode à
appeler est déterminé à la compilation.



Que veut dire "signature" ?


C'est l'identité de la méthode: nom + paramètres + type de retour +
classe associée.


Par contre, le choix de l'implémentation de la méthode est dynamique,
c'est à dire déterminé à l'exécution (ce qui

permet de le polymorphisme).

Dans l'exemple, tu appelles uneAutreMethode(), sur une référence de
type A (soit ri). Le compilo va chercher si la classe A possède une
signature de méthode correspondante



quelle est-elle dans cet exemple?


La signature ?

void uneAutreMethode(), de l'interface A.

Et donc erreur car A ne déclare pas cette méthode.

(ce qui n'est pas le cas -> erreur de compile)

et ce alors même que tu sais, toi, qu'à l'exécution ri pointera bien
sur une instance de B, qui possède cette signature de méthode.



Dans cet exemple qu'est ce qui permet de dire que l'implémentation de la
méthode est dynamique?


Rien. En Java, le choix de l'implémentation de la méthode est toujours
dynamique car il dépend de l'instance sur laquelle tu appelles la
méthode * à l'exécution *. (ce qui n'est pas tjrs vrai mais bon,
faisons simple)





1 2 3