Ir al contenido


Foto

Crear clase u objeto y acceder a el


  • Por favor identifícate para responder
23 respuestas en este tema

#21 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 09 abril 2013 - 07:21

Hola edorantes Para lograr un diseño como el que buscas:



delphi
  1. MisUsuarios.Show(0).GetNombre;



Habría que hacer unos cuantos cambios.
A como lo tienes desarrollado no es posible llegar a esa forma. Considero que la forma más sencilla y que no te afecta demasiado a tu código es que además de ese Show le puedes declarar justamente los Getters que necesites. Y como dije: estos por necesidad deben recibir el índice. Es decir por ejemplo:



delphi
  1. function TUsuarios.GetNombre(Indice: integer): string;
  2. begin
  3.   result := nombreU[Indice]; // o que es igual a result := nombreU.Strings[Indice];
  4. end;



Hay una forma de llegar a un diseño como que deseas... pero para ello se debe ir a por lo último que te comenté: separar en dos clases: Una clase que mantenga la lista, la que llamé TUsuarios y otra la que hace a cada usuario: TUsuario.

Luego se puede añadir un método GetUsuario() a la clase TUsuarios que regrese el TUsuario correspondiente según el índice. Algo como:



delphi
  1. function TUsuarios.GetUsuario(Indice: integer): TUsuario;
  2. begin
  3.   result := FLista.Items[Indice] as TUsuario; // o también result := TUsuario(FLista.Items[Indice]);
  4. end;



Entonces cuando uno llama a ese método, recibe al objeto de la clase TUsuario correspondiente. Y como esta clase ya cuenta con métodos/propiedades para acceder a cada atributo es que entonces podemos hacer cosas como:



delphi
  1. Edit2.Text := MisUsuarios.GetUsuario(5).Nombre;



En el ejemplo se GetUsuario devuelve al objeto que está 6to en la lista (recuerda que los índices en los TxxxList empiezan por 0 [cero]). Luego es que se accede a la propiedad Nombre.

Este diseño lleva a que se tenga que crear tantas instancias de TUsuario como se necesiten. Justamente se puede aprovechar a la clase TUsuarios para que asuma esta responsabilidad (ya que de paso se encarga de poner/sacar dicha lista), basta con añadirle un método que haga el trabajo. Algo como:



delphi
  1. function TUsuarios.NewUsuario(ID: integer; SupCder, SupSder: Currency, Nombre, Cultivo: string): integer;
  2. var User: TUsuario;
  3. begin
  4.   User := TUsuario.Create;
  5.   User.ID := ID;
  6.   User.Nombre := Nombre;
  7.   User.SupCDer := SupCder;
  8.   User.SupSder := SupSder;
  9.   User.Cultivo := Cultivo;
  10.  
  11.   result := FLista.Add(TObject(User));
  12. end;



Fíjate que aprovecho este método para no sólo ya crear el Usuario y llenarlo con la información necesaria sino que además, ya de paso lo agrego en la lista. Al ser una función el método regresa justamente el índice o posición.

Si se contase con este método ya no haría falta tener que estar creando por nuestros propios medios a los objetos de la clase Usuarios, ya le hemos dado la capacidad a TUsuarios.

Como notas finales:
1)En tu código que acabas de poner estás invocando a una clase y no a un objeto o instancia de ésta. Fíjate que estás haciendo:



delphi
  1. Tusuarios.Show(0).getNombre



Cuando es:



delphi
  1. var MisUsuarios: TUsuarios;
  2. ...
  3. MisUsuarios.Show(0).getNombre;



Por algo recomiendo seguir la nomeclatura de Delphi. Se acostumbra a anteponer a nuestras clases el prefijo T, de modo que es TAlgo, para diferenciar de los nombres de los objetos de la misma. Por tanto:

TUsuarios >> Nombre de la clase
Usuarios >> Nombre de un objeto

2) Es IntToStr() y no IntToString.

Saludos,
  • 0

#22 edorantes

edorantes

    Advanced Member

  • Miembros
  • PipPipPip
  • 78 mensajes

Escrito 11 abril 2013 - 09:08

Gracias amigo ya quedo asi mira


delphi
  1. unit uUsuarios;
  2.  
  3. interface
  4.  
  5. uses classes, Types, SysUtils, DM;
  6.  
  7. type
  8.  
  9. //Aqui defino mis propios tipos de variables
  10. TIntArray    = array[0..15] of shortint;
  11. TSingleArray = array[0..15] of currency;
  12.  
  13.   Tusuarios = class(TObject)
  14.   Constructor Create;
  15.  
  16.   private
  17.   idU, cuentaU, subcU  :  TIntArray;
  18.   supCder, supSder,totalU    :  TSingleArray;
  19.   nombreU, cultivoU    :  TStrings;
  20.   ap : shortint;  {Apuntador, lleva el numero de recibos en el cobro actual}
  21.  
  22.   public
  23.  
  24.   procedure inicializa();
  25.   procedure add(id : Integer; cuenta :Integer; Sub : Shortint; nombre : String; supConDer : Currency ; supSinDer:Currency; cultivo:String;total : Currency) ;
  26.   // procedure delete(id : shortint);
  27.  
  28.   function GetID(Indice: Shortint) :Integer;
  29.   function GetNombre  (Indice: Shortint) :string;
  30.   function GetSupCder (Indice : Shortint):Currency;
  31.   function GetSupSder (Indice : Shortint) :Currency;
  32.   function GetCultivo (Indice : Shortint) :string;
  33.   function GetImporteU(Indice : Shortint):Currency;
  34.   function GetImporteTotal:currency;
  35.   function GetCuenta  (Indice :Shortint):string;
  36.   function GetSubcuenta  (Indice :Shortint):string;
  37.  
  38.   end;
  39.  
  40. implementation
  41.  
  42. uses Math;
  43.  
  44. constructor Tusuarios.create;
  45. begin
  46.  
  47.   nombreU := Tstringlist.create;
  48.   cultivoU := Tstringlist.create;
  49.   ap := 0;
  50.  
  51.  
  52.  
  53.  
  54.  
  55. end;
  56.  
  57. procedure Tusuarios.inicializa;
  58. begin
  59.   ap := 0; //inicializamos ap que es el apuntador
  60. end;
  61.  
  62. procedure Tusuarios.add (id : Integer;cuenta :Integer; Sub : Shortint; nombre
  63.   :String;supConDer : Currency ; supSinDer:Currency; cultivo:String; total :Currency);
  64. begin
  65.     idU[ap] := id;
  66.     cuentaU[ap] := cuenta;
  67.     subcU[ap]:= Sub;
  68.     nombreU.Add(nombre);
  69.     supCder[ap] := supConDer;
  70.     supSder[ap] := supSinDer;
  71.     cultivoU.Add(cultivo);
  72.     totalU[ap] := total;
  73.     ap := ap+1;
  74. end;
  75.  
  76. function TUsuarios.GetID(Indice: Shortint): Integer;
  77. begin
  78.   result := idU[Indice];
  79. end;
  80.  
  81. function TUsuarios.GetNombre(Indice: Shortint): string;
  82. begin
  83.   result := nombreU[Indice];
  84. end;
  85.  
  86. function TUsuarios.GetSupCDer(Indice: Shortint): Currency;
  87. begin
  88.   result := supCder[Indice];
  89. end;
  90.  
  91. function TUsuarios.GetSupSDer(Indice: Shortint): Currency;
  92. begin
  93.   result := supSder[Indice];
  94. end;
  95.  
  96. function TUsuarios.GetCultivo(Indice: Shortint): string;
  97. begin
  98.   result := cultivoU[Indice];
  99.  
  100. end;
  101.  
  102. function TUsuarios.GetImporteU(Indice: shortint): Currency;
  103. begin
  104.   result := totalU[indice];
  105. end;
  106.  
  107. function TUsuarios.GetImporteTotal: Currency;
  108. var i : Shortint;
  109. begin
  110.   for i := 0 to 15 do begin
  111.  
  112.   Result :=totalU[i]+totalU[i];
  113.   end;
  114.  
  115. end;
  116.  
  117. function TUsuarios.GetCuenta(Indice: Shortint): String;
  118. begin
  119.   result := IntToStr(cuentaU[Indice]);
  120. end;
  121.  
  122. function TUsuarios.GetSubcuenta(Indice: Shortint): String;
  123. begin
  124.   result := IntToStr(subcU[indice]);
  125.  
  126. end;
  127.  
  128.  
  129.  
  130.  
  131. end.



pero tengo otra duda,en la parte de GetImporteTotal es donde saco el importe de todos los usuarios pero siempre me saca 0 no se por que asi esta



delphi
  1. function TUsuarios.GetImporteTotal: Currency;
  2. var i : Shortint;
  3. begin
  4.   for i := 0 to 15 do begin
  5.  
  6.   Result :=totalU[i]+totalU[i];
  7.   end;
  8.  
  9. end;


Si ves otros errores me avisas,Tambien no se como eliminar un elemento de un array espero puedas ayudarme
Bendiciones
  • 0

#23 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 11 abril 2013 - 07:23

Hola edorantes,
Me parece que no estás leyendo con la debida atención mis palabras. No puedes eliminar elementos del array. Al ser estático y fijo no se puede dimensionar, por tanto siempre tendrá reservado el tamaño indicado.
La única vía para borrar o eliminar de éste es sobreescribir en la posición determinada con valores nulos o vacios. Por ejemplo: si es un integer, que sea 0 (cero), a un string con cadena vacía; etc.
En donde si puedes proceder con una liberación será en los TStrings.
Por esto te he comentado que lo más adecuado para resolver el tema es llevar un diseño basado en dos clases: una clase que administre una lista de otra. De este modo uno puede añadir, borrar, insertar, y/o modificar a su antojo sin preocuparse de estar declarando arrays de tamaños fijos.

Y aún si a esos arrays los declararas de forma dinámica:



delphi
  1. type
  2.   TArrayDinamico = array of Double;



Tendrás serias dificultades para llevar a cabo una eliminación debido a que deberás implementar un algoritmo de "corrimiento" y sobreescritura de una posición por la anterior/siguiente. Es decir, supongamos que inicialmente tu tienes el vector de tamaño 10:



delphi
  1. SetLength(MiVector, 10);



Y más adelante debes eliminar el 5to elemento:
1 - 2 - 3 - 4 - x - 5 - 6 - 7 - 8 - 9 - 10

El nuevo vector deberá entonces contener el dato de los 9:
1 - 2 - 3 - 4 - 6 - 7 - 8 - 9 - 10

Esto se consigue reemplazando lo que hay en la 5ta posición por la 6ta, el de 6ta por la 7ma y así hasta llegar al final. Luego si ya es posible redimensionar:



delphi
  1. SetLength(MiVector, 9);



Si en lugar de este diseño lo hubieras llevado a un planteo de dos clases como el que expuse basta con emplear aprovechar la clase TObjectList para armar la lista. La clase TObjectList es capaz de agregar, insertar y eliminar objetos de manera totalmente transparente y sin problemas. ¡Chau vectores!

Tu estás mezclando la "vieja escuela" con la nueva... estás mezclando estructurado con OO. De poder se puede, pero en la forma en como lo estás llevando es, con toda disculpas, caótica. Como ya he dicho: estás almacenando cada atributo en vectores/listas por separado. En su lugar aconsejo definir una propia clase que contenga a estos atributos y luego por tanto armar una lista con objetos de esta clase.

Respecto a tu duda sobre GetImporteTotal fíjate que estás sobreescribiendo el valor de result y no acumulándolo.  ;)

Y como nota final: yo reemplazaría el shortint por integer. A menos que en verdad existiera una imperiosa necesidad de "ahorrarse" bytes yo me decantaría directamente a pasarlo a integer. En una arquitectura de 32-bits el registro de la CPU son de 32-bits por lo que de todas formas el compilador va tener que enmascarar al tipo en un registro de 32-bits.
De hecho, en el ciclo el compilador va a utilizar el registro contador y este ya es de 32. El forzarlo a que sea de shortint simplemente no ahorra nada, solo genera indirección y se malgasta ciclos de procesamiento.

Saludos,
  • 0

#24 edorantes

edorantes

    Advanced Member

  • Miembros
  • PipPipPip
  • 78 mensajes

Escrito 29 abril 2013 - 03:40

Gracias Delphius por tus consejos, esta todo resuelto para poner vaciar el arreglo solo bastaba con poner el apuntador en ceros
muchas gracias
  • 0




IP.Board spam blocked by CleanTalk.