Ir al contenido


Foto

Como generar Unit con POO


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

#1 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 15 abril 2016 - 04:53

Bueno una unidad con orientacion a objetos entre otras que hice..quiero que la corrijan.

 

La cree escribiendo.. 


php
  1. property NombreAtributo

y luego el compilador genero el codigo de los setter colocandolos en "private"


delphi
  1. unit UProducto;
  2.  
  3. interface
  4. type
  5. Tproducto = class
  6. private
  7. Fcosto: Double;
  8. Fiva: double;
  9. Fprecio: Double;
  10. Fpedir: boolean;
  11. Fsubcategoria: string;
  12. Fcategoria: string;
  13. Fpreciob: Double;
  14. Fporcganancia: Double;
  15. Fprecioa: Double;
  16. Fidproducto: integer;
  17. Fnombre: string;
  18. Fmarca: string;
  19. Fganancia: Double;
  20. procedure Setcategoria(const Value: string);
  21. procedure Setcosto(const Value: Double);
  22. procedure Setganancia(const Value: Double);
  23. procedure Setidproducto(const Value: integer);
  24. procedure Setiva(const Value: double);
  25. procedure Setmarca(const Value: string);
  26. procedure Setnombre(const Value: string);
  27. procedure Setpedir(const Value: boolean);
  28. procedure Setporcganancia(const Value: Double);
  29. procedure Setprecio(const Value: Double);
  30. procedure Setprecioa(const Value: Double);
  31. procedure Setpreciob(const Value: Double);
  32. procedure Setsubcategoria(const Value: string);
  33. property idproducto:integer read Fidproducto write Setidproducto;
  34. property categoria:string read Fcategoria write Setcategoria;
  35. property subcategoria:string read Fsubcategoria write Setsubcategoria;
  36. property marca:string read Fmarca write Setmarca;
  37. property costo:Double read Fcosto write Setcosto;
  38. property precio:Double read Fprecio write Setprecio;
  39. property iva:double read Fiva write Setiva;
  40. property pedir:boolean read Fpedir write Setpedir;
  41. property nombre:string read Fnombre write Setnombre;
  42. property preciob:Double read Fpreciob write Setpreciob;
  43. property precioa:Double read Fprecioa write Setprecioa;
  44. property ganancia:Double read Fganancia write Setganancia;
  45. property porcganancia:Double read Fporcganancia write Setporcganancia;
  46. public
  47. constructor create(idproducto:integer;categoria:string;subcategoria:string;marca:string;
  48. costo:Double;precio:Double;iva:Double;pedir:Boolean;nombre:String;preciob:Double;precioa:double;
  49. ganancia:Double;porcganancia:Double);
  50. end;
  51. implementation
  52.  
  53. { Tproducto }
  54.  
  55.  
  56.  
  57. constructor Tproducto.create(idproducto: integer; categoria, subcategoria,
  58. marca: string; costo, precio, iva: Double; pedir: Boolean; nombre: String;
  59. preciob, precioa, ganancia, porcganancia: Double);
  60. begin
  61.  
  62. Fidproducto:=idproducto;
  63. Fcategoria:=categoria;
  64. Fsubcategoria:=subcategoria;
  65. Fmarca:=marca;
  66. Fcosto:=costo;
  67. Fprecio:=precio;
  68. Fiva:=iva;
  69. Fpedir:=pedir;
  70. Fnombre:=nombre;
  71. Fpreciob:=preciob;
  72. Fprecioa:=precioa;
  73. Fganancia:=ganancia;
  74. Fporcganancia:=porcganancia;
  75. end;
  76.  
  77. procedure Tproducto.Setcategoria(const Value: string);
  78. begin
  79. Fcategoria := Value;
  80. end;
  81.  
  82. procedure Tproducto.Setcosto(const Value: Double);
  83. begin
  84. Fcosto := Value;
  85. end;
  86.  
  87. procedure Tproducto.Setganancia(const Value: Double);
  88. begin
  89. Fganancia := Value;
  90. end;
  91.  
  92. procedure Tproducto.Setidproducto(const Value: integer);
  93. begin
  94. Fidproducto := Value;
  95. end;
  96.  
  97. procedure Tproducto.Setiva(const Value: double);
  98. begin
  99. Fiva := Value;
  100. end;
  101.  
  102. procedure Tproducto.Setmarca(const Value: string);
  103. begin
  104. Fmarca := Value;
  105. end;
  106.  
  107. procedure Tproducto.Setnombre(const Value: string);
  108. begin
  109. Fnombre := Value;
  110. end;
  111.  
  112. procedure Tproducto.Setpedir(const Value: boolean);
  113. begin
  114. Fpedir := Value;
  115. end;
  116.  
  117. procedure Tproducto.Setporcganancia(const Value: Double);
  118. begin
  119. Fporcganancia := Value;
  120. end;
  121.  
  122. procedure Tproducto.Setprecio(const Value: Double);
  123. begin
  124. Fprecio := Value;
  125. end;
  126.  
  127. procedure Tproducto.Setprecioa(const Value: Double);
  128. begin
  129. Fprecioa := Value;
  130. end;
  131.  
  132. procedure Tproducto.Setpreciob(const Value: Double);
  133. begin
  134. Fpreciob := Value;
  135. end;
  136.  
  137. procedure Tproducto.Setsubcategoria(const Value: string);
  138. begin
  139. Fsubcategoria := Value;
  140. end;
  141.  
  142. end.

No genero los getter.

Y por ultimo programe la implementación del constructor..

 

Agradezco me corrijan


  • 0

#2 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 539 mensajes
  • LocationCali, Colombia

Escrito 15 abril 2016 - 06:32

 

 

Hola, creo que los procedimientos que debes ejecutar fuera de la clase, deben ir en Protected si se heredarán para ser usados o modificados desde una clase heredada o Public si se deben ejecutar desde afuera.

 

En cuanto a las propiedades no pueden estar en una sección privada, debería estar en la sección Public o en su defecto en Published si son clases para utilizar en el IDE y publicar estas propiedades en el Object Inspector.

 

De resto esa clase está bien hasta aquí.

 

Saludos.


  • 1

#3 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 15 abril 2016 - 08:46

La sintaxis general es
 


delphi
  1. property Nombre: [b]Tipo [/b]read Getter write Setter;

Donde en la seccion read debe especificarse bien:

  • Una funcion sin argumentos que retorne Tipo
  • Una variable de instancia de Tipo

Ademas, al especificar read, estamos diciendo implicitamente que (obviamente teniendo en cuenta las reglas de visibilidad segun sea private, protected, public) el valor de la propiedad se puede leer
 
En la seccion write debe especificarse bien:

  • Un procedimiento con un solo argumento (pudiendo ser un agumento const), de Tipo
  • Una variable de instancia de Tipo

El write implicitamente esta diciendo que el valor de esa propiedad se puede modificar
 
En tiempo de ejecucion, al usar una propiedad, en el caso en que estemos asignando un valor (operador de asignacion comun, :=) se ejecuta lo que dice la seccion write. Es decir, si hay un metodo, se ejecuta ese metodo y se envia como argumento el valor que estamos asignando
 


delphi
  1. property Nombre: string read GetNombre write SetNombre;
  2.  
  3. procedure TClas.SetNombre(const Value: string);
  4. begin
  5. FNombre := Value;
  6. end;
  7.  
  8. procedure TClase.GetNombre: string;
  9. begin
  10. Result := FNombre;
  11. end;
  12.  
  13. ...
  14. var
  15. c: TClase;
  16. begin
  17. ...
  18.  
  19. c.Nombre := 'Pedro'; // estas dos lineas son equivalentes
  20. c.SetNombre('Pedro');
  21. end;

Para el caso de las lecturas es lo mismo


delphi
  1. var
  2. c: TClase;
  3. begin
  4. ..
  5. ShowMessage(c.Nombre);
  6. ShowMessage(c.GetNombre);
  7. end;

Por que automaticamente se mandan los getter y setter a la seccion private?

 

Simplemente porque la propiedad es suficiente para hacer las dos cosas; en un solo "metodo" agrupas dos. El codigo queda mas legible y ademas a la hora de escribir es mucho mas comodo

 

Si sacamos las propiedades, y dejamos los getter y setter como publicos, tendriamos el doble de metodos disponibles para usar en la clase

 

Ademas el codigo queda mas limpio usando propiedades. Usando el setter estamos obligados a escribir entre parentesis el valor a escribir


delphi
  1. c.SetNombre('Pedrito');

A mi siempre me molestan los parentesis. Que pasa si ahi dentro en lugar de pedrito hay que mandar, algo que tambien tiene parentesis (operaciones matematicas, otorgar formato al string, invocar al metodo de otra clase que requiere parametros, etc)

 

 

Las propiedades mas que nada existen para ayudar al desarrollador. Son mas "lindas", mas limpias y mas comodas de usar que los getter y los setter. La funcion que cumplen es la misma que la de ellos 

 

Luego hay algunos usos mas sofisticados de las propiedades, como por ejemplo acceder mediante un indice

 

 

Ejemplos:


delphi
  1. ShowMessage(Strings.Items[0]);
  2. Strings[5] := 'Pedrito'

Cuando el equivalente podria ser


delphi
  1. ShowMessage(Strings.GetItem(0))
  2. Strings.SetItem(5, 'Pedrito')


  • 0

#4 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 15 abril 2016 - 10:38

De acuerdo...dentro de todo esta bien..convengamos que es una clase solamente, no hay mucha complejidad..mas adelante posteare mas..

 

Y en la clase factura que voy a exponer mas adelante tengo:


delphi
  1. Fproductos: array of Tproducto;

y no me lo coloca en el constructor..esta mal declarado?

 

ya lo solucione con:


delphi
  1. type
  2. arrayProductos = Class (TObjectList<Tproducto>);


  • 0

#5 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 539 mensajes
  • LocationCali, Colombia

Escrito 15 abril 2016 - 12:42

Bien, esta parte es la más interesante,  cuando manejas una lista o un arreglo de objetos, lo ideal es que definas la clase padre, para que todos los "hijos" puedan ir en la lista.

 

Regreso al ejemplo de los objetos de dibujo. 

 

TPunto = Class(TObject);

TLinea = Class(TPunto);

TRectangulo = Class(TLinea);

TCirculo = Class(TLinea).

 

Se crea todo el manejo de las listas para TPunto y nada más que para el,   así administrar una línea, un rectángulo o un circulo es indiferente para la lista.

 

En una POO bien diseñada,  lo único que se debe cambiar es la rutina de adición del objeto a la lista,  luego el manejo de cada objeto es prácticamente autonómo.

 

Saludos.


  • 0

#6 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 16 abril 2016 - 06:37

Bien, esta parte es la más interesante,  cuando manejas una lista o un arreglo de objetos, lo ideal es que definas la clase padre, para que todos los "hijos" puedan ir en la lista.

 

Regreso al ejemplo de los objetos de dibujo. 

 

TPunto = Class(TObject);

TLinea = Class(TPunto);

TRectangulo = Class(TLinea);

TCirculo = Class(TLinea).

 

Se crea todo el manejo de las listas para TPunto y nada más que para el,   así administrar una línea, un rectángulo o un circulo es indiferente para la lista.

 

En una POO bien diseñada,  lo único que se debe cambiar es la rutina de adición del objeto a la lista,  luego el manejo de cada objeto es prácticamente autonómo.

 

Saludos.

Entonces tu dices no hacerlo con TObjectList.. aunque se podria

 

Y seria entonces crear la lista como una clase que luego requiere instanciarce...aqui encontre una pagina:

 

http://www.devmedia....em-delphi/23962

 

Esta en portugues pero mirando el codigo..crea una clase "listaclientes" que luego instancia con metodos adicionar y remover..

 

Es eso?

 

Saludos


  • 0

#7 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 16 abril 2016 - 07:01

una cosa que no encuentro es como declarar la implementacion de una clase hija... por el tema de la asignacion de valores a los atributos heredados de la clase padre..

Por ejemplo FacturaA hereda de Factura y se especializa con 3 atributos de alicuotas...

 

el constructor se llama NuevoCompA


delphi
  1. constructor TFacturaA.NuevoCompA(alicuota21, alicuota10, alicuota27: Double);
  2. begin
  3. Falicuota21:=alicuota21;
  4. Falicuota10:=alicuota10;
  5. Falicuota27:=alicuota27;
  6. end;

este es el constructor de la clase padre


delphi
  1. constructor NuevoComp(Persona:TPersona;importe:Double;fechae:string;
  2. horae,FCAE:string;sucursal:integer;efectivo:Double;vuelto:Double);


  • 0

#8 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 539 mensajes
  • LocationCali, Colombia

Escrito 16 abril 2016 - 08:09

Veamos el ejemplo de heredad de las clases.

delphi
  1. TPunto = Class(TObject)
  2. Private
  3.    FX : Integer;
  4.    FY : Integer;
  5.    FColor  : TColor;
  6.  Public
  7.      Constructor Create(aX, aY : Integer; aColor :
  8. TColor); Virtual;
  9.      Procedure Dibujar(Canvas : TCanvas); Virtual;
  10. End;
  11.  
  12. TLinea = Class(TPunto)
  13. Private
  14.   FX1 : Integer;
  15.   FY1 : Integer;
  16. Public
  17.   Constructor Create(Ax, aY, aX1, aY1 : Integer; aColor : TColor);
  18. Reintroduce;
  19.   Procedure Dibujar(Canvas : TCanvas); Override;
  20. End;
  21.  
  22. Implementation
  23.  
  24. Constructor TLinea.Create(aX, aY, aX1, aY1 : Integer; aColor : TColor);
  25. Begin
  26.     Inherited Create(aX, aY, aColor);  ///Invoca el
  27. constructor del padre
  28.     FX1 := aX1;
  29.     FY1 := aY1;
  30. End;

En este caso, se maneja una sola lista que puede ser una colección de objetos de tipo punto, lo único que debe modificarse es la adición de los objetos a la lista, el resto, cada objeto debería ser lo más autónomo posible.
 
Ej.

delphi
  1. Var
  2.    ListaDibujo = TList<TPunto>;

Para dibujar en un canvas sería algo así.

delphi
  1.   Var Punto : TPunto;
  2.  
  3.   For Punto in ListaDibujo do
  4.      Punto.Dibujar(Image1.Canvas);

  La lista, puede contener objetos de todos los tipos heredados de TPunto y los entenderá bien a la hora de dibujarlos.
 
Esto aplica para cualquier tipo de programación orientada a objetos. 
 
Saludos.
  • 0

#9 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 16 abril 2016 - 08:16

Ok entiendo...

 

entonces la herencia quedaria(y ya con la lista):


delphi
  1. constructor TFacturaA.NuevoCompA(alicuota21, alicuota10, alicuota27: Double);
  2. var
  3. listaProductos: TList<Tproducto>;
  4. begin
  5. Inherited Create(Persona,importe,fechae,horae,sucursal,efectivo,vuelto);
  6. Falicuota21:=alicuota21;
  7. Falicuota10:=alicuota10;
  8. Falicuota27:=alicuota27;
  9. end;

despues bueno habria que agregar productos y/o quitarlos..

Para lo mismo pienso usar una interfaz ya que depende del tipo de factura es como se agregan los productos se calculan los impuestos y totales..etc.. Lo publicare mas adelante asi lo miran..

el CAE lo obtengo del servidor de AFIP..por eso no obligo a establecerlo en el constructor..


  • 0

#10 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 16 abril 2016 - 08:28

Ahora bien..otra duda..una clase que hereda de otra? puede implementar una interfaz.

Porque he buscado como decir en codigo que una clase implementa una interfaz.. usando InterfacedObject..pero se pueden declarar las dos cosas a la vez?

 

Porque facturaA hereda al igual que FacturaB de factura..entonces.. puedo tener una interfaz para las operaciones como por ej:


delphi
  1. unit UIOperaciones;
  2.  
  3. interface
  4. type
  5. IOperacionesAB = interface
  6. procedure calculoAlicuotas(iva:Double;subtotal:Double);
  7. end;
  8.  
  9. IOperaciones = interface
  10.  
  11. procedure imprimir();
  12. procedure guardarPDF();
  13. procedure agregaProducto();
  14. end;
  15. implementation
  16.  
  17. end.

porque la idea mia es que cada clase de factura implemente los metodos como le corresponde.,.que es ese el concepto de interfaz..

 

entonces como declaro que facturaA hereda de factura e implementa una interfaz?

mo sera que la clase padre factura debe implementar la interfaz entonces todas las clases hijas redefinen los metodos


  • 0

#11 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 16 abril 2016 - 09:46

Podes usar delegación. Busca sobre ello en la docwiki. La palabra clave de interes es implements
 
Básicamente declaras una clase como que implementa una interface, pero dicha implementación no se hace en la clase, sino no en otra. Luego, podes usar la clase como si realmente implementara la interface
 
Revisa este ejemplo:
 

delphi
  1. unit Unit2;
  2.  
  3. interface
  4.  
  5. type
  6. IImprimible = interface
  7. ['{F470F0CB-FB49-4215-8E17-85862237E7E2}']
  8. procedure Imprimir(const PageCount: Integer = 1);
  9. end;
  10.  
  11. TDocumento = class abstract
  12. end;
  13.  
  14. TFactura = class(TDocumento, IImprimible)
  15. private
  16. FImpresora: IImprimible;
  17. function GetImpresora: IImprimible;
  18. public
  19. constructor Create(const AImpresora: IImprimible);
  20. property Impresora: IImprimible read GetImpresora implements IImprimible;
  21. // property Impresora: IImprimible read FImpresora implements IImprimible; equivalentes
  22. end;
  23.  
  24. TImprimirdorFacturaA = class(TInterfacedObject, IImprimible)
  25. procedure Imprimir(const PageCount: Integer = 1);
  26. end;
  27.  
  28. TImprimirdorFacturaB = class(TInterfacedObject, IImprimible)
  29. procedure Imprimir(const PageCount: Integer = 1);
  30. end;
  31.  
  32. implementation
  33.  
  34. { TFactura }
  35.  
  36. constructor TFactura.Create(const AImpresora: IImprimible);
  37. begin
  38. inherited Create;
  39. FImpresora := AImpresora;
  40. end;
  41.  
  42. function TFactura.GetImpresora: IImprimible;
  43. begin
  44. Result := FImpresora;
  45. end;
  46.  
  47. { TImprimirdorFacturaB }
  48.  
  49. procedure TImprimirdorFacturaB.Imprimir(const PageCount: Integer);
  50. begin
  51. Writeln('Se esta imprimiendo la Factura B...');
  52. end;
  53.  
  54. { TImprimirdorFacturaA }
  55.  
  56. procedure TImprimirdorFacturaA.Imprimir(const PageCount: Integer);
  57. begin
  58. Writeln('Se esta imprimiendo la Factura A...');
  59. end;
  60.  
  61. end.

Uso:


delphi
  1. uses
  2. System.SysUtils,
  3. Unit2 in 'Unit2.pas';
  4.  
  5. var
  6. fcA, fcB: IImprimible;
  7. begin
  8. try
  9. fcA := TFactura.Create(TImprimirdorFacturaA.Create);
  10. fcB := TFactura.Create(TImprimirdorFacturaB.Create);
  11.  
  12. fcA.Imprimir;
  13. fcB.Imprimir;
  14.  
  15. Readln;
  16. except
  17. on E: Exception do
  18. Writeln(E.ClassName, ': ', E.Message);
  19. end;
  20. end.


  • 0

#12 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 16 abril 2016 - 09:55

Ok..y el diseño que planteo es bueno? Aunque depende lo ke cada uno piensa.

Enviado desde mi SM-G530M mediante Tapatalk
  • 0

#13 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 16 abril 2016 - 11:21

 

 

La delegación se caracteriza por "reutilización selectiva", en cambio en herencia es un "todo o nada".

A ver si entiendo un poco

De hecho coloque en uioperaciones.pas dos interfaces..dado que las facturas A y B tiene por ejemplo el iva discriminado.. y la C el iva incluido..

Pero ademas: los metodos imprimir y guardarPDF y demas yo los necesito en las clases concretas.. es decir yo en el sistema voy a instanciar..de acuerdo a las condiciones de iva una factura A o B o C pero no una factura..osea la clase madre no se instancia digamos.. estos metodos podrian estar en la clase madre y ser implementados de distinta manera..

La otra alternativa es usar interfaces...que es parecido a una clase abstracta.. son metodos cuya implementacion se desarrolla en cada clase

 

podria ser factura una clase con metodos abstractos (los que estan en la interfaz) y que luego los defina factura a y b..

 

lo que no me permite el compilador es esto que hiciste agustin:


delphi
  1. TFactura = class(TDocumento, IImprimible)

osea colocar la clase padre y una interfaz...

 

asi me quedo:


delphi
  1. unit UFactura;
  2.  
  3. interface
  4. uses
  5. UPersona,Uproducto,UIOperaciones,Generics.collections,SysUtils;
  6. type
  7.  
  8. TFactura = class abstract
  9. private
  10. FCAE: string;
  11. Fimporte: Double;
  12. Fpersona: TPersona;
  13. Fvuelto: Double;
  14. Fefectivo: Double;
  15. Fhorae: string;
  16. Fsucursal: integer;
  17. Ffechae: string;
  18.  
  19. procedure SetCAE(const Value: string);
  20. procedure Setefectivo(const Value: Double);
  21. procedure Setfechae(const Value: string);
  22. procedure Sethorae(const Value: string);
  23. procedure Setimporte(const Value: Double);
  24. procedure Setpersona(const Value: TPersona);
  25.  
  26. procedure Setsucursal(const Value: integer);
  27. procedure Setvuelto(const Value: Double);
  28.  
  29. property CAE:string read FCAE write SetCAE;
  30. property persona:TPersona read Fpersona write Setpersona;
  31. property importe:Double read Fimporte write Setimporte;
  32. property fechae:string read Ffechae write Setfechae;
  33. property horae:string read Fhorae write Sethorae;
  34. property sucursal:integer read Fsucursal write Setsucursal;
  35. property efectivo:Double read Fefectivo write Setefectivo;
  36. property vuelto:Double read Fvuelto write Setvuelto;
  37.  
  38. public
  39. constructor NuevoComp(Persona:TPersona;importe:Double;fechae:string;
  40. horae:string;sucursal:integer;efectivo:Double;vuelto:Double);
  41. procedure calculoAlicuotas(iva:Double;subtotal:Double);virtual;abstract;
  42. procedure agregaProducto(p:Tproducto);virtual;abstract;
  43. procedure quitaProducto(p:Tproducto);virtual;abstract;
  44. procedure imprimir();virtual;abstract;
  45. procedure guardarPDF(rutaDestino:string);
  46. destructor Destroy;
  47. end;
  48.  
  49. TFacturaA = class (TFactura)
  50.  
  51. private
  52. Falicuota21: Double;
  53. Falicuota27: Double;
  54. Falicuota10: Double;
  55. procedure Setalicuota10(const Value: Double);
  56. procedure Setalicuota21(const Value: Double);
  57. procedure Setalicuota27(const Value: Double);
  58.  
  59. property alicuota21:Double read Falicuota21 write Setalicuota21;
  60. property alicuota10:Double read Falicuota10 write Setalicuota10;
  61. property alicuota27:Double read Falicuota27 write Setalicuota27;
  62. public
  63. const
  64. iva21 = 21;
  65. iva10 = 10.5;
  66. iva27 = 27;
  67. constructor NuevoCompA(alicuota21:Double;alicuota10:Double;alicuota27:Double);
  68. destructor Destroy;
  69. procedure calculoAlicuotas(iva:Double;subtotal:Double);
  70. procedure agregaProducto(p:Tproducto) ;
  71. procedure quitaProducto(p:Tproducto);
  72. procedure imprimir();
  73. procedure guardarPDF(rutaDestino:string);
  74. end;
  75. TFacturaB = class (TFactura)
  76.  
  77. private
  78. Falicuota21: Double;
  79. procedure Setalicuota21(const Value: Double);
  80. property alicuota21:Double read Falicuota21 write Setalicuota21;
  81. public
  82. const
  83. iva = 21;
  84. constructor NuevocompB(alicuota21:Double);
  85. destructor Destroy;
  86. procedure agregaProducto(p:Tproducto);
  87. procedure quitaProducto(p:Tproducto);
  88. end;
  89. implementation
  90.  
  91. { TFactura }
  92.  
  93.  
  94.  
  95.  
  96. destructor TFactura.Destroy;
  97. begin
  98.  
  99. end;
  100.  
  101.  
  102. procedure TFactura.guardarPDF(rutaDestino: string);
  103. begin
  104.  
  105. end;
  106.  
  107. constructor TFactura.NuevoComp(Persona: TPersona; importe: Double; fechae,
  108. horae: string; sucursal: integer; efectivo, vuelto: Double);
  109. begin
  110.  
  111. Fimporte:=importe;
  112. Fpersona:=Persona;
  113. Fvuelto:=vuelto;
  114. Fefectivo:=efectivo;
  115. Fhorae:=horae;
  116. Fsucursal:=sucursal;
  117. Ffechae:=fechae;
  118.  
  119. end;
  120.  
  121.  
  122.  
  123. procedure TFactura.SetCAE(const Value: string);
  124. begin
  125. FCAE := Value;
  126. end;
  127.  
  128. procedure TFactura.Setefectivo(const Value: Double);
  129. begin
  130. Fefectivo := Value;
  131. end;
  132.  
  133. procedure TFactura.Setfechae(const Value: string);
  134. begin
  135. Ffechae := Value;
  136. end;
  137.  
  138. procedure TFactura.Sethorae(const Value: string);
  139. begin
  140. Fhorae := Value;
  141. end;
  142.  
  143. procedure TFactura.Setimporte(const Value: Double);
  144. begin
  145. Fimporte := Value;
  146. end;
  147.  
  148. procedure TFactura.Setpersona(const Value: TPersona);
  149. begin
  150. Fpersona := Value;
  151. end;
  152.  
  153.  
  154. procedure TFactura.Setsucursal(const Value: integer);
  155. begin
  156. Fsucursal := Value;
  157. end;
  158.  
  159. procedure TFactura.Setvuelto(const Value: Double);
  160. begin
  161. Fvuelto := Value;
  162. end;
  163.  
  164. { TFacturaA }
  165.  
  166. procedure TFacturaA.agregaProducto(p: Tproducto);
  167. var
  168. prod:Tproducto;
  169. begin
  170.  
  171. end;
  172.  
  173. procedure TFacturaA.calculoAlicuotas(iva, subtotal: Double);
  174. begin
  175.  
  176. end;
  177.  
  178. destructor TFacturaA.Destroy;
  179. begin
  180.  
  181. end;
  182.  
  183. procedure TFacturaA.guardarPDF(rutaDestino: string);
  184. begin
  185.  
  186. end;
  187.  
  188. procedure TFacturaA.imprimir;
  189. begin
  190.  
  191. end;
  192.  
  193. constructor TFacturaA.NuevoCompA(alicuota21, alicuota10, alicuota27: Double);
  194. var
  195. listaProductos: TList<Tproducto>;
  196. begin
  197. Inherited Create();
  198. Falicuota21:=alicuota21;
  199. Falicuota10:=alicuota10;
  200. Falicuota27:=alicuota27;
  201. end;
  202.  
  203. procedure TFacturaA.quitaProducto(p: Tproducto);
  204. begin
  205.  
  206. end;
  207.  
  208. procedure TFacturaA.Setalicuota10(const Value: Double);
  209. begin
  210. Falicuota10 := Value;
  211. end;
  212.  
  213. procedure TFacturaA.Setalicuota21(const Value: Double);
  214. begin
  215. Falicuota21 := Value;
  216. end;
  217.  
  218. procedure TFacturaA.Setalicuota27(const Value: Double);
  219. begin
  220. Falicuota27 := Value;
  221. end;
  222.  
  223. { TFacturaB }
  224.  
  225. procedure TFacturaB.agregaProducto(p: Tproducto);
  226. begin
  227.  
  228. end;
  229.  
  230. destructor TFacturaB.Destroy;
  231. begin
  232.  
  233. end;
  234.  
  235. constructor TFacturaB.NuevocompB(alicuota21: Double);
  236. begin
  237. Inherited Create();
  238. Falicuota21:=alicuota21;
  239. end;
  240.  
  241. procedure TFacturaB.quitaProducto(p: Tproducto);
  242. begin
  243.  
  244. end;
  245.  
  246. procedure TFacturaB.Setalicuota21(const Value: Double);
  247. begin
  248. Falicuota21 := Value;
  249. end;
  250.  
  251. end.


  • 0

#14 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 16 abril 2016 - 12:29

Por que no te lo permite? Que error arroja?

 

Puede no permitirte compilar porque en la clase te falta implementar los metodos de la interface

 

En ese caso tenes dos formas, o bien los implementas, o bien usas delegacion, que es justamente lo que mostre arriba con el implements

 

Yo no pondria en la clase TFactura nada relacionado con imprimir ni con guardar a PDF

 

Eso lo trabajaria en una rama aparte. Los reporteadores lo hacen de manera similar, por eso es necesario colocar componentes "extras", los filtros, que son los que realizan el trabajo

 

Yo haria esto:


delphi
  1. type
  2. IExportadorFacturas = interface
  3. procedure Exportar(AFactura: TFactura; const ANombreArchivo: string);
  4. end;
  5.  
  6. TExportadorPDF = class(TInterfacedObject, IExportadorFacturas)
  7. procedure Exportar(AFactura: TFactura; const ANombreArchivo: string);
  8. end;
  9.  
  10. TExportadorExcel = class(TInterfacedObject, IExportadorFacturas)
  11. procedure Exportar(AFactura: TFactura; const ANombreArchivo: string);
  12. end;

Luego, uso en codigo:


delphi
  1. procedure ExportarComoPdf(AFactura: TFactura; const ANombreArchivo: string);
  2. var
  3. AExportador: IExportadorFacturas;
  4. begin
  5. AExportador := TExportadorPdf.Create;
  6. AExportador.Exportar(AFactura, ANombreArchivo);
  7. end;
  8.  
  9. procedure BotonExportarPdfClick(Sender: TObject);
  10. var
  11. AFactura: TFactura;
  12. begin
  13. AFactura := // obtener factura de algun repositorio de datos, etc
  14. try
  15. ExportarComoPdf(AFactura);
  16. finally
  17. AFactura.Free
  18. end;
  19. end;


  • 0

#15 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 17 abril 2016 - 06:37

Claro..lo que yo no tengo es el numero que aparece abajo de interface en tu codigo... y ademas tengo la interface en un archivo aparte..tiene algo que ver?

 

 

 

Yo no pondria en la clase TFactura nada relacionado con imprimir ni con guardar a PDF

 

es correcto porque ademas son metodos independiente del tipo o clase de factura. Guardar se guarda nomas un archivo..lo que cambia es la forma del pdf nomas..

 

Y el error que da es

 

[dcc32 Error] UFactura.pas(48): E2291 Missing implementation of interface method IInterface.QueryInterface

 

es conocido lo busque en google y claro poniendo la palabar INterfacedObject se soluciona.. pero no me sirve


  • 0

#16 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 17 abril 2016 - 08:40

No creo que sea problema del Guid. Eso lo generas desde el IDE apretando control shift g

No importa que esté en un archivo aparte, siempre y cuando lo pongas en el

Podes publicar el código conflictivo?
  • 0

#17 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 17 abril 2016 - 01:31

esta es la clase factura


delphi
  1. unit UFactura;
  2.  
  3. interface
  4. uses
  5. UPersona,Uproducto,UIOperaciones,Generics.collections,SysUtils;
  6. type
  7.  
  8. TFactura = class
  9. private
  10. FCAE: string;
  11. Fimporte: Double;
  12. Fpersona: TPersona;
  13. Fvuelto: Double;
  14. Fefectivo: Double;
  15. Fhorae: string;
  16. Fsucursal: integer;
  17. Ffechae: string;
  18. Fproductos: TList<Tproducto>;
  19.  
  20. procedure SetCAE(const Value: string);
  21. procedure Setefectivo(const Value: Double);
  22. procedure Setfechae(const Value: string);
  23. procedure Sethorae(const Value: string);
  24. procedure Setimporte(const Value: Double);
  25. procedure Setpersona(const Value: TPersona);
  26.  
  27. procedure Setsucursal(const Value: integer);
  28. procedure Setvuelto(const Value: Double);
  29. procedure Setproductos(const Value: TList<Tproducto>);
  30.  
  31. property CAE:string read FCAE write SetCAE;
  32. property persona:TPersona read Fpersona write Setpersona;
  33. property importe:Double read Fimporte write Setimporte;
  34. property fechae:string read Ffechae write Setfechae;
  35. property horae:string read Fhorae write Sethorae;
  36. property sucursal:integer read Fsucursal write Setsucursal;
  37. property efectivo:Double read Fefectivo write Setefectivo;
  38. property vuelto:Double read Fvuelto write Setvuelto;
  39. property productos:TList<Tproducto> read Fproductos write Setproductos;
  40. public
  41. constructor NuevoComp(Persona:TPersona;importe:Double;fechae:string;
  42. horae:string;sucursal:integer;efectivo:Double;vuelto:Double;productos:TList<Tproducto>);
  43. procedure calculoAlicuotas();
  44. procedure agregaProducto(p:Tproducto);
  45. procedure quitaProducto(p:Tproducto);
  46.  
  47. destructor Destroy;
  48. end;

cuando hago


delphi
  1. TFacturaA = class (TFactura, IOperacionesAB)

me da ese error.. y si pongo punto y coma despues del parentesis.. me dice

 

[dcc32 Error] UFactura.pas(54): E2029 '=' expected but identifier 'Falicuota21' found

 

alicuota21 es el primer parametro que tengo..

 

igual logre hacerlo implementando las interfaces en la clase madre factura luego cada factura sobreescribe lo que necesita..por ejemplo la factura c no implementa calculoAlicuotas..solo agregar producto por ej..estaria bien?


  • 0

#18 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 18 abril 2016 - 10:43

Bueno en internet encontre que el detalle puede ser una clase que compone a la clase factura.. entonces pense tener 3 clase hijas heredando de detalle..un detalle por cada tipo de factura respectivamente. a su vez se puede componer de una cabecera y de un pie.

 

Lo que si la clase factura no tendria porque especializarse..porque de detalle heredan los distintos tipos..

Al momento de facturar se ingresa el CUIT o se selecciona un cliente... de acuerdo a su condicion tributaria se creara un objeto detalle a b o c para poder crear un objeto factura.

me parece mejor que tener tres clases de factura..aunque se puede implementar de las dos formas..


  • 0




IP.Board spam blocked by CleanTalk.