Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: Kayla - Novembre 27, 2014, 11:26:20 pm

Titolo: Classe con riferimeto ad altra classe
Inserito da: Kayla - Novembre 27, 2014, 11:26:20 pm
Vorrei creare una struttura che permetta di accedere ai valori inseritiin un'altra classe

ipotesi Materiali generici e vano Cucina
ad es. creo dei materiali Legno, Granito, Marmo in foma generica

quando vado nella Cucina vorrei leggere i materiali creati nella classe Materiali,
a quanto pare mi manca qualcosa, per ottenere il risultato cercato.

spero in qualche indicazione, anche se nell'ultimo post, nella sezione Databases, ho fatto confusione con gli apici.

Codice: [Seleziona]
 type TMateriali = class(TObject)
   private
     FMateriale: TStringList;
     FUnMisura: string;

   public
     function SetMateriali: TStringList;
 end;

 type TCucina = class(TObject)
   private
    FLunghezza: integer;
    FTipo: TStringList;
    FMateriali:TMateriali;  //qui dovrei avere il riferimento a TMateriali

   public
    procedure SetCucina;
 end;

function TMateriali.SetMateriali: TStringList;
//var FMatesElenco: TStringList;
begin
  FMateriale:= TStringList.Create;
  FMateriale.Add('Legno');
  FMateriale.Add('Granito');
  FMateriale.Add('Marmo');

  Result := FMateriale;
end;

{ TCucina }

function TCucina.SetCucina: TStringList;
begin
 FTipo := TStringList.Create;
 FTipo := FMateriali.FMateriale;  //qui ovviamente FMateriali è=nil e non posso leggere FMateriale
end;
Titolo: Re:Classe con riferimeto ad altra classe
Inserito da: nomorelogic - Novembre 29, 2014, 11:22:43 am
ciao scusa la risposta in ritardo, non so se ho ben interpretato ma intanto ora funziona e si può ragionarci sopra

ho messo le tue dichiarazioni in una unit chiamata Unit2
Codice: [Seleziona]
unit Unit2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;

type
  TMateriali = class(TObject)
  private
    FUnMisura: string;
  public
    FMateriale: TStringList; // spostata sotto public, prima era pirvate
    function SetMateriali: TStringList;
  end;

  TCucina = class(TObject)
  private
    FLunghezza: integer;
    FTipo: TStringList;
  public
    FMateriali: TMateriali;  //qui dovrei avere il riferimento a TMateriali
    procedure SetCucina;
  end;



implementation

{ TCucina }

procedure TCucina.SetCucina;
begin
  FTipo := TStringList.Create;
  FTipo.AddStrings(FMateriali.FMateriale);
end;

{ TMateriali }

function TMateriali.SetMateriali: TStringList;
begin
  FMateriale := TStringList.Create;
  FMateriale.Add('Legno');
  FMateriale.Add('Granito');
  FMateriale.Add('Marmo');

  Result := FMateriale;
end;


end.


poi in una form ho messo un bottone ed un memo (Memo1), nell'onclick del bottone ho messo il seguente codice:

Codice: [Seleziona]
procedure TForm1.Button1Click(Sender: TObject);
var m: TMateriali;
    c: TCucina;
begin
   m := TMateriali.Create;

   c := TCucina.Create;
   m.SetMateriali;
   c.FMateriali := m;
   c.SetCucina;

   memo1.Lines.AddStrings(c.FMateriali.FMateriale);
end;

Titolo: Re:Classe con riferimeto ad altra classe
Inserito da: Kayla - Novembre 29, 2014, 10:47:04 pm
Grazie per la disponibilita', cerchero' di modificare per avere delle property.
fermo restando che la tua modifica funziona.

Potrei usare delle variabili FTipoMateriale, etc. per il fatto che la StringList e' legata alla posizione di inserimento
cosi se Legno viene inserito non per primo elemento
Codice: [Seleziona]
  FMateriale := TStringList.Create;
  FMateriale.Add('Granito');
  FMateriale.Add('Legno');
testando FMateriale[0] cambierette tutto

potrei ricorere alla procedure che ritorna per valore , ma dovrei fare una classe per
Legno, Marmo, Granito , etc

Codice: [Seleziona]
 type TMateriali = class(TObject)
   private
     FUnMisura: string;
     FTipoMateriale: string;

   public
     FMateriale: TStringList;
     procedure SetMateriali(var FTipoLegno, FUnitaMisura: string);
 end;

e nel form

Codice: [Seleziona]
procedure SetMateriali(var FTipoLegno, FUnitaMisura: string);
begin
  FTipoMateriale := 'Legno';
  FUnitaMisura := 'Mq';
end;
questo sistema, non permette di inserire piu' di 1 elemento alla volta.

Al momento sono a corto di idee.

L'idea di base e' costruire un sistema che permette (ampliando le classi) di costruire un ambiente scegliendo
Materiale, e le altre caratteristiche, ma senza farlo direttamente nel form

es: A
Cucina-Top->Granito
Cucina-Pavimento->Cermica
Cucna-Mobili->Legno

ma la stessa cosa per B potrebbe essere
Cucina-Top->Marmo
Cucna-Mobili->Laminato

sono sulla strada corretta o e' troppo tortuosa ?
Titolo: Re:Classe con riferimeto ad altra classe
Inserito da: nomorelogic - Novembre 30, 2014, 10:43:28 am
Visto che ci sei oltre ad usare le property dovresti usare anche i costruttori di classe ed i rispettivi distruttori (constructor e destructor).
Così facendo il tuo codice si avvicinerebbe di più a quelli che sono gli standard di codifica oop (= più facile capire le tue intenzioni).

I materiali non li devi testare con la posizione ma con il metodo IndexOf: http://www.freepascal.org/docs-html/rtl/classes/tstringlist.indexof.html (http://www.freepascal.org/docs-html/rtl/classes/tstringlist.indexof.html)
In questo modo il test prescinde dalla posizione, ad esempio:
Codice: [Seleziona]
if FMateriale.IndexOf('Legno') >= 0 then
   ShowMessage('è di legno!');


Per inserire più informazioni su una stringlist puoi usare la capacità di memorizzare coppie "nome"="valore" in una unica stringa.
In questo modo puoi fare:
FMateriale.Add('Legno=Mq');
FMateriale.Add('Granito=Kg');

in questo caso, per testare invece di indexof puoi usare IndexOfName http://www.freepascal.org/docs-html/rtl/classes/tstrings.indexofname.html (http://www.freepascal.org/docs-html/rtl/classes/tstrings.indexofname.html)
Codice: [Seleziona]
if FMateriale.IndexOfName('Legno') >= 0 then
   ShowMessage('è di legno!');

per avere l'unità di misura:
Codice: [Seleziona]
var um:string;
begin
   ...
   um := FMateriale.Values['Legno'];
   ...
end;


se hai bisogno di altri dati oltre l'UM (es: spessore, sotto categoria materiale, bordo toroidale, trattamenti vari, ecc...), allora bisogna che ci ragioniamo sopra ;)
Titolo: Re:Classe con riferimeto ad altra classe
Inserito da: Kayla - Dicembre 03, 2014, 09:46:59 am
grazie delle indicazioni, le proprieta' IndexOf e IndexOfName di una TStgingList, proprio non le conoscevo; veramente utili.

su property + constructor e distructor; ci passo un po' di tempo e poi aggiorno.