Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++ [ Archives / Divers ] (cbonus2000)

mercredi 6 octobre 2004 à 19:07:07 | (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

cbonus2000


Salut,
peux-t-on en Delphi (tout comme en C++) faire une classe qui dérive de deux autres classes.

Pour faire cà facile au début:
Par exemple, j'ai une classe ITEM, qui contient les propriétés LONGUEUR et LARGEUR, puis elle peut contenir des descendants comme: 1- la classe ITEM-ROULEAU qui contient en plus une propriété DIAMETRE ou 2- un autre Descendant nommé ITEM-FEUILLE qui lui possède en plus de Longueur et Largeur une propriété HAUTEUR.

Donc nous nous retrouvons en résumé avec

ITEM = class(?)
property Longueur
property Largeur

ITEM-ROULEAU = Class(ITEM)
property Diametre

ITEM-FEUILLE = Class(ITEM)
property Hauteur

Là où sa se complique c'est que ITEM, je veux qu'il dérive dans certains un cas de la Classe ENTETE-COMMANDE qui lui possède la propriété NO-ORDER, et dans un autre Cas la classe ITEM dérive de la classe FAVORI-CLIENT qui lui possède la propriété NO-CLIENT, ADRESSE, TEL.


Donc sa ressemble à:

ENTETE-COMMANDE = class(?)
property NO-ORDER

FAVORI-CLIENT = Class(?)
property NO-CLIENT
property ADRESSE
property TEL

et

ITEM = CLass(ENTETE-COMMANDE , FAVORI-CLIENT) ????
property Longueur
property Largeur



Comment implanter ITEM. Je crois qu'on peut s'en sortir avec les interfaces, mais comment? J'en sais rien..
_______
Bonus

jeudi 7 octobre 2004 à 00:20:39 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

Delphiprog

Administrateur CodeS-SourceS
Précision importante : le Pascal Objet n'autorise pas l'héritage multiple. Nous verrons plus loin qu'il n'est d'ailleurs pas le seul langage dans ce cas.
En revanche, on peut y parvenir indirectement en utilisant les interfaces. Cette solution est bien plus élégante, propre et moins risquée que l'héritage multiple qui est un nid à problème avec le C++.

A la lecture de la première partie des questions, tu affirmes que Item "peut contenir des descendants". Je ne vois pas comment une classe mère peut contenir des classes filles qui sont ses héritières...Qui fût le premier : la poule ou l'oeuf ? voilà une question à laquelle personne en peur répondre et qui reste donc non résolue à ce jour.
Or, dans l'esquisse de déclaration que tu donnes en dessous, on voit que les classes Item_Rouleau et Item_Feuille descendent purement et simplement de la classe Item. Nous retombons bien sur le principe de l'héritage simple. Je ne pense pas qu'il soit nécessaire d'expliquer davantage ce concept, sinon je te renvoie à la littérature abondante traitant de ce sujet.

Venons en à la deuxième partie (la plus intéressante à mon goût).
Pour la suite des explications, j'utilise la convention de notation de Borland, à savoir :
- chaque nom de classe est précédé de la lettre T pour désigner un type
- chaque nom d'interface est précédé de la lettre I pour indiquer une interface.
Ces quelques principes peuvent éviter bien des confusions dans le code par la suite quand il faudra instancier des objets.

Je vais reprendre les mots que tu as employés et les analyser.
je veux qu'il dérive dans certains un cas de la Classe ENTETE-COMMANDE et et dans un autre Cas la classe ITEM dérive de la classe FAVORI-CLIENT.
Cela veut donc dire que tantôt un objet de la classe TItem devra se comporter comme s'il était du type TEnteteCommande et tantôt comme s'il était du type TFavoriClient.
Voilà donc un candidat parfait pour l'utilisation des interfaces !

Pour bien comprendre les interfaces, il faut les imaginer comme des contrats type, décrivant les méthodes (sous entendu des comportements) que les classes qui s'engageront à les utiliser devront respecter à la lettre.
Prenons l'exemple de l'en-tête de commande :

IOrderHeader = interface
function GetNoOrder: integer;
procedure SetNoOrder(Value: integer);
end;


Les classes qui signeront le contrat avec cette interface IOrderHeader devront donc implémenter deux méthodes. Comme on peut le deviner en lisant les noms de ces 2 méthodes, elles serviront à accèder à la propriété NoOrder. Comme rien n'était précisé dans l'exposé du problème, j'ai supposé que ces propriétés seraient en lecture+écriture.

Passons à la déclaration de la classe implémentant les méthodes GetNoOrder et SetNoOrder.
ATTENTION : dans les déclarations des classes ci-dessous, je n'ai pas mentionné les champs destinés à stocker les valeurs des propriétés pour ne pas alourdir davantage la présentation.

TOrderHeader = class(TInterfacedObject, IOrderHeader)
public
//méthodes de l'interface IOrderHeader
function GetNoOrder: integer;
procedure SetNoOrder(Value: integer);

property NoOrder: integer read GetNoOrder write SetNoOrder;
end;


Par souci de réutilisabilité, je fais hériter la classe TOrderHeader de la classe TInterfacedObject de manière à ne pas avoir à réimplémenter les méthode _AddRef, _Release et QueryInterface déclarées dans l'interface IUnknown (IUnKnown est aux interfaces ce que la classe TObject est aux classes).

Pratiquons selon la même démarche en ce qui concerne la classe nommée TFavoriClient :

IFavoriClient = interface
function GetNoClient: integer;
function GetAdresse: string;
function GetTel: string;

procedure SetNoClient(Value: integer);
procedure SetAdresse(Value: string);
procedure SetTel(Value: string);
end;

TFavoriClient = class(TInterfacedObject, IFavoriClient)
public
//méthodes de l'interface IFavoriClient
function GetNoClient: integer;
function GetAdresse: string;
function GetTel: string;

procedure SetNoClient(Value: integer);
procedure SetAdresse(Value: string);
procedure SetTel(Value: string);

property NoClient: integer read GetNoClient write SetNoClient;
property Adresse: string read GetAdresse write SetAdresse;
property Tel: string read GetTel write SetTel;
end;

Nous voilà donc avec deux classes implémentant deux interfaces différentes.
Alors, comment faire pour en obtenir une troisième qui aura la qualité des deux autres ?
C'est simple :

TItem = class(TInterfacedObject, IOrderHeader, IFavoriClient)
private
//méthodes de l'interface IOrderHeader
function GetNoOrder: integer;
procedure SetNoOrder(Value: integer);
//Méthodes de l'interface IFavoriClient
function GetNoClient: integer;
function GetAdresse: string;
function GetTel: string;

procedure SetNoClient(Value: integer);
procedure SetAdresse(Value: string);
procedure SetTel(Value: string);
public

end;


La classe TItem va implémenter les méthodes des interfaces IOrderHeader et IFavoriClient et respecte le contrat de départ signé avec celles-ci.

Comme dernière précision, je dirais qu'une interface peut être vue comme un pointeur sur une table de méthodes.
Déclarons l'usage d'interfaces :

var
//attention à bien déclarer des interfaces et NON des classes !
Order: IItem;
Favori: IItem;
//explications plus loin...
CodeCommande: integer;
AdresseClient: string;


Instancions ensuite un objet Item qui se comportera comme une en-tête de commande :

//Instanciation
Order:= TItem.Create as IOrderHeader;

on utilise cette interface comme si de rien n'était :

CodeCommande := Order.GetNoOrder;
//changement de cap !
Favori:= Order as IFavoriClient;
AdresseClient := Favori.GetAdresse;


Je vais arrêter là les explications. Il y a tellement de choses à dire sur ce sujet.
Si tu es parvenu à lire jusqu'ici, alors je t'adresse mes félicitations...pour ta patience.
Expliquer la technique d'utilisation des interfaces en quelques lignes est impossible. Si tu souhaites aller plus loin, je t'invite à te tourner vers des ouvrages techniques. Ce ne sera pas du temps perdu. D'autres langages comme Java, PHP (depuis la version 5) utilisent cette technique extrêmement puissante et bien moins scabreuse que l'héritage multiple auquel tous les langages ont renoncé sauf un : le C++.
Il doit bien y avoir une raison...

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you

jeudi 7 octobre 2004 à 14:13:56 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

cbonus2000


Salut,

et oui, je suis parvenu à tout lire le texte du début à la fin.... faut dire que le sujet m'intéressait beaucoup... Pour ce qui est des interface et des classes, je connaissais déjà la plupart des concepts et des nomenclatures... Mais c'était essentiellement l'héritage multiple sur lequel je m'interrogeais... Je savais que sa se faisait par interface et que surment Borland avait fait de quoi de simple, mais me restait seulement à savoir comment... By the way, encore une fois merci de ton temps et de tes précisions méticuleuses...

Merci

_______
Bonus

vendredi 8 octobre 2004 à 18:10:50 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

jobtunisieyasser

tu doit cliquer Réponse acceptée ! sur le message de Delphiprog et non pas sur ton message
en plus
Delphiprog il ne répond qu'au message vraiment cousteau
alors répond à la mienne :)
http://www.delphifr.com/forum.v2.aspx?ID=310613
@_______=-Jobtunisie-=_______@
|..................NOURON ALA NOUR.......................|

mardi 26 octobre 2004 à 03:09:06 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

cbonus2000

Salut,

mon information est un peu incomplète.

La classe IITEM n'est pas déclaré ci-haut. Doit-elle dérivé à la fois de IOrderHeader et de IFavoriClient?

Lorsque je fais la ligne suivante:
Order:= TItem.Create as IOrderHeader

d'où
Order: IItem;

le compilateur indique une erreur:
Incompatible type 'TItem' and 'IOrderHeader'

Comment l'interface IItem peut -elle dérivé de deux autres interfaces? C'est quoi l'autre solution, si je présume que il y en a efectivement une autre? Il me manque un petit bout pour résoudre le casse-tête. Seulement la déclaration de IItem.

Merci de votre patience


_______
Bonus

mercredi 3 novembre 2004 à 03:33:36 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

cbonus2000


Bon et bien,

pour me répondre à moi meme.. je crois que sa se fait pas en delphi 7. Avec .Net oui, à ce que la littérature dit, mais de l'héritage multiple avec Delphi 7, la littérature semble prétendre que non, à moins qu'on me prouve le contraire.

Le seul moyen de s'en sortir, c'est donc de faire de l'aggréation,
par exemple:


type
IOrderHeader = interface
[etc..]
end;

TOrderHeader = class(TObject, IOrderHeader)
FMyItem: IItem;
property FMyItem: IItem read FMyItem implements IItem;
end;

var
MyClass: TOrderHeader ;
MyInterface: IItem;
begin
MyClass := TMyClass.Create;
MyClass.FMyInterface := ...
// some object whose class implements IItem

MyInterface := MyClass;
MyInterface.ProcedureEtc..;
end;

Donc c'est cà!
_______
Bonus

samedi 6 novembre 2004 à 10:57:20 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

Delphiprog

Administrateur CodeS-SourceS
Tiens, voici un bon tutorial sur les interfaces situé sur le site de Michel BARDOU.

Pourquoi tiens-tu absolument à cette notion d'héritage multiple ?
Je suis très surpris que la littérature mentionne la possibilité de l'héritage multiple avec .Net. Voici ce que dit un extrait de la documentation livrée avec le .Net framework SDK à la rubrique "héritage multiple":
"À la différence des autres types, qui sont dérivés uniquement d'un type de base unique, une interface peut être dérivée de plusieurs interfaces de base. Dès lors, une interface peut hériter de membres de type de même nom à partir de différentes interfaces de base. Dans ce cas, le nom hérité plusieurs fois n'est pas disponible dans l'interface dérivée, et toute référence à l'un de ces membres de type par l'intermédiaire de l'interface dérivée provoque une erreur de compilation, peu importe les signatures ou la surcharge. Au lieu de cela, les membres de type en conflit doivent être référencés via un nom d'interface de base."

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you

jeudi 5 juillet 2007 à 13:11:28 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

mounjetado

j'aurais une question à propos de l'utilisation d'une interface.
si on a plusieurs projets ds un groupe de projets, dt certains sont des appli console et d'autres des appli VCL avec GUI, 
         peut-on partager des propriétés ou des données via plusieurs interfaces (par exemple, une interface permet l'accès en lecture, une autre en écriture), ou est-ce que les-dites propriétés sont propres à une interface?
         quelle est la visibilité d'une instance d'interface?
         peut-on instancier un objet d'une classe faisant référence à plusieurs interfaces dans l'appli principale, pour ensuite utiliser les instances d'interfaces chacune dans une appli console différente, tout en partageant des propriétés ou des données, ainsi que leur accès évidemment?


si Delphi m'était conté...

lundi 22 septembre 2008 à 18:52:21 | Re : (Niveau Élevé) POO- Comment en Delphi faire une classe qui hérite de deux autres classes comme on fais en C++

jeromefer

Bonjour a tous

Merci beaucoup à Delphiprog pour l'explication claire.
J'apprecie toujours vos conseils et je les les mets toujours en application car
on sens que c'est du vecu !

Je buttais depuis plusieurs jours sur un probleme similaire  !
Merci

Jerome



Cette discussion est classé dans : class, client, item, classe, property


Répondre à ce message

Sujets en rapport avec ce message

POP3 et SSL [ par botelec ] Bonjours à tous et toutes ! Voila, j'ai implémenter une classe client mail multi-thread à partir de la classe TClientSocket afin de me passé d'Indy o constante de classe [ par Guillemouze ] Salut a tous,Mon problème n'est pas un problème, c'est plutôt un avis a vous demander.J'ai une classe mère TMere qui fait un paquet de traitements, do Auto complétion [ par jcaction ] Bonjour à tous, Je débute en delphi et je crée une application de base de données avec la version7. Mon problème est que je voudrais permettre lors de TCollection : changement de stratégie [ par Francky23012301 ] Salut à tous,Je suis entrain d'utiliser les TCollections : seulement je ne suis pas satisfait du résultat . Je vous colle la partie qui me plait pas : réseau entre deux poste [ par tmsource ] Salut t.mJ'ai deux postes de travail (A comme serveur & B comme client) lier par un câble réseaux rg45, je peux explorer tous les répertoires partagés client-serveur en delphi [ par anafor ] bonjour jusqu'ici, je developpais des applications monopostes avec delphi 7  et oracle par des liens udl mais à présent,mon encadreur veut que je deve Utilisation de composant des une classe [ par DjKill77 ] Bonjour à toutes et à tous, J'aimerais réaliser un chat sous delphi, mais je m'impose une programmation en objet histoire de faire un code propre et m TCustomWinSocket [ par Bacterius ] Bonjour, bon je rencontre un problème : j'ai, de façon générale, 2 applications 1 application serveur : - 1 TServerSocket 1 application client : - Création de composant : probleme de liaison de sous-propriété [ par orelien ] Bonjour,Je souhaite faire fonctionner le code suivant :... type  TPosition = class(TPersistent)  private    FX : Real;    FY : Real;    FReference: Dialogue client/serveur avec les compo FTP indy [ par John Dogget ] Salut à tous.J'écris actuellement un petit client FTP avec les compo indy de Delphi 7.Ca marche pas trop mal pour l'instant mais je voudrais y rajoute


Nos sponsors

Sondage...

CalendriCode

Octobre 2008
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,265 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.