In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Herencias

Foro público de Xailer en español
Responder
zeasoftware
Mensajes: 1831
Registrado: Mar Oct 11, 2005 9:53 am

Herencias

Mensaje por zeasoftware »

Segun mis conocimientos de OOP, cuando hago un objeto o clase, puedo pasarlo
como herencia a un objeto hijo, el cual hereda los metodos, datos, etc.
En el caso de los metodos estos los podria reescribir sin afectar al metodo
padre, o sea, ke si el evento padre tiene un metodo llamado calcular() ke
haga a+b, en el objeto hijo puedo redefinir ke calcular haga a-b, asi
funciona en Xailer?.
Esto lo pregunto por ke estoy haciendo una relacion de todo lo ke
nececitaria para hacer una clase comun para hacer altas, bajas, cambios y
consultas de una base de datos, la cual sea comun los metodos ke hagan cada
una de las operaciones, pero, veo ke al crear la forma tengo ke asignar los
valores a los DataSet, DataSource, etc. por lo cual, al principio ke haga mi
clase tDBFCommon, tendria ke anexarle las asignaciones de dichos valores,
sin tener ke reescribir el codigo de la creacion de la forma.
Haber si asi me explico mejor:
Class tDBFCommon From tForm
Component oDataSet
blah blah
Method CreateForm()
EndClass
METHOD CreateForm() CLASS tDBFCommon
Super:CreateForm()
::SetBounds( 382, 329, 504, 422 )
::oFont := TFont():Create( "MS Sans Serif", 8, 0, 400 )
::nBorderStyle := bsDIALOG
::Create()
Return ( Self )
//esto lo haria en las classes ke los procedimientos son comunes
Class tArticulos From tDBFCommon
blah blah
EndClass
METHOD CreateForm() CLASS tArticulos
With Object ::oParent
:CreateForm()
:cText := "Datos del Producto"
:nClientWidth := 496
:nClientHeight := 388
End
WITH OBJECT ::oDataSource := TCdxDataSource():New( Self )
:Create()
END
WITH OBJECT ::oDataSet := TDbfDataSet():New( Self )
:oDataSource := ::oDataSource
:cProcess := "GENERAL"
:cName := "DatosLineas.dbf"
:lOpen := .T.
:Create()
END
Return ( Self )
Se puede?
Si en algo estoy mal o equivocado mil gracias por dedirmelo.
Gracias.
Ramon Zea
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5706
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Herencias

Mensaje por jfgimenez »

Ramón,
(es curioso, pero tu mensje es de hace una semana y ha aparecido hoy!!!)
> Segun mis conocimientos de OOP, cuando hago un objeto o clase, puedo
> pasarlo como herencia a un objeto hijo, el cual hereda los metodos, datos,
> etc.
> En el caso de los metodos estos los podria reescribir sin afectar al
> metodo padre, o sea, ke si el evento padre tiene un metodo llamado
> calcular() ke haga a+b, en el objeto hijo puedo redefinir ke calcular haga
> a-b, asi funciona en Xailer?.
Si, como cualquier otro sistema OOP
> Esto lo pregunto por ke estoy haciendo una relacion de todo lo ke
> nececitaria para hacer una clase comun para hacer altas, bajas, cambios y
> consultas de una base de datos, la cual sea comun los metodos ke hagan
> cada una de las operaciones, pero, veo ke al crear la forma tengo ke
> asignar los valores a los DataSet, DataSource, etc. por lo cual, al
> principio ke haga mi clase tDBFCommon, tendria ke anexarle las
> asignaciones de dichos valores, sin tener ke reescribir el codigo de la
> creacion de la forma.
>
> Haber si asi me explico mejor:
>
> Class tDBFCommon From tForm
> Component oDataSet
> blah blah
>
> Method CreateForm()
> EndClass
>
> METHOD CreateForm() CLASS tDBFCommon
>
> Super:CreateForm()
> ::SetBounds( 382, 329, 504, 422 )
> ::oFont := TFont():Create( "MS Sans Serif", 8, 0, 400 )
> ::nBorderStyle := bsDIALOG
> ::Create()
> Return ( Self )
Ojo con CreateForm()... Este método es el que contruye el formulario y todos
los controles y componentes que contenga, pero lo crea directamente el IDE
cuando creas un nuevo formulario, y en ningún momento hace una llamada a
Super:CreateForm(), por lo que nunca se llamará a este método de la clase
padre. Por lo tanto, si escribes este método en la clase base de tus
mantenimientos, cuando creas un nuevo formulario basado en esa clase, nunca
se va a ejecutar el código anterior; a no ser que modifiques los ficheros
..xfm, lo que no es nada aconsejable, porque tendrías que hacerlo con un
editor distinto al IDE, y cada vez que abras ese módulo con el IDE te lo va
a volver a cambiar.
Si quieres escribir un método que siempre se ejecute, hazlo con New() o con
Create(), pero llamando siempre a Super:xxx antes de tu propio código.
P.ej.:
METHOD New( oParent ) CLASS TDBFCommon
Super:New( oParent )
// Aqui viene tu codigo
RETURN Self
o
METHOD Create( oParent ) CLASS TDBFCommon
Super:Create( oParent )
// Aqui viene tu codigo
RETURN Self
En el caso de New(), al llegar a tu código ya están creados tanto el
formulario como todos los componentes y controles que contenga, y en el caso
de Create(), sólo estará contruido el formulario, pero sin componentes ni
controles. Pero ten en cuenta que esta regla sólo es válida para los
formularios, no para los controles; en el caso de los controles, sólo te
serviría sobreescribir el método Create(), pero no el New().
> //esto lo haria en las classes ke los procedimientos son comunes
>
> Class tArticulos From tDBFCommon
> blah blah
>
> EndClass
>
> METHOD CreateForm() CLASS tArticulos
>
> With Object ::oParent
> :CreateForm()
Aquí hay un error de concepto... ::oParent es el 'padre' del formulario, no
la clase padre. El padre del formulario es normalmente otro formulario, o en
su defecto, Application. Es exactamente el objeto que le pases al método
New(). Pero para llamar a un método de la clase padre, tienes que usar
Super:xxxxx(). En este caso, tendrías que haber puesto Super:CreateForm()
> :cText := "Datos del Producto"
> :nClientWidth := 496
> :nClientHeight := 388
A causa de lo anterior, esto también es incorrecto. Utiliza el operador Self
o ::
Creo que tu error de concepto se debe a que no tienes claro qué es una clase
y qué es un objeto. Intentaré aclaratelo un poco, pero te aconsejo que
estudies mejor los conceptos de la OOP.
En OOP, cuando accedes a un miembro de la propia clase (usando Self o ::) y
este miembro no está presente en la clase actual sino en su clase padre, en
realidad accedes al miembro de la clase padre; no necesitas el operador
Super. Y algo parecido ocurre al revés, si accedes a un miembro de una
clase, y ese miembro está redeclarado en una clase hija, y el objeto
correspondiente es una instancia de la clase hija, en realidad estás
accediendo al miembro de la clase hija. Todo esto se debe a que de hecho,
nunca trabajas directamente sobre las clases, sino sobre objetos, que son
instancias de las clases. P.ej:
CLASS UNO
DATA a INIT "A"
DATA b INIT "B"
METHOD Test() INLINE ::a + ::b
ENDCLASS
CLASS DOS FROM UNO
DATA a INIT "1"
ENDCLASS
PROCEDURE Main()
LOCAL uno := UNO() // Instanciar la clase UNO
LOCAL dos := DOS() // Instanciar la clase DOS
? uno:a // "A"
? uno:b // "B"
? uno:Test() // "AB"
? dos:a // "1"
? dos:b // "B"
? dos:Test() // "1B", a pesar de que Test() esta solamente en UNO
RETURN
Este ejemplo lo puedes probar directamente con [x]Harbour, sin necesidad de
Xailer. Espero que te aclare un poco el mecanismo de la herencia en OOP.
>
> End
>
> WITH OBJECT ::oDataSource := TCdxDataSource():New( Self )
> :Create()
> END
>
> WITH OBJECT ::oDataSet := TDbfDataSet():New( Self )
> :oDataSource := ::oDataSource
> :cProcess := "GENERAL"
> :cName := "DatosLineas.dbf"
> :lOpen := .T.
> :Create()
> END
>
> Return ( Self )
>
> Se puede?
> Si en algo estoy mal o equivocado mil gracias por dedirmelo.
--
Un saludo,
José F. Giménez
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
jariasv
Mensajes: 9
Registrado: Sab Dic 18, 2004 2:47 pm

Herencias

Mensaje por jariasv »

xHarbour Compiler build 0.99.3 (SimpLex)
Copyright 1999-2004, http://www.xharbour.org http://www.harbour-project.org/
Compiling 'oop1.prg'...
oop1.prg(1) Error E0030 Syntax error: "parse error at 'UNO'"
oop1.prg(2) Error E0030 Syntax error: "parse error at 'A'"
oop1.prg(3) Error E0030 Syntax error: "parse error at 'B'"
oop1.prg(4) Error E0030 Syntax error: "parse error at 'TEST'"
oop1.prg(5) Error E0020 Incomplete statement or unbalanced delimiters
oop1.prg(7) Error E0030 Syntax error: "parse error at 'DOS'"
oop1.prg(8) Error E0030 Syntax error: "parse error at 'A'"
oop1.prg(9) Error E0020 Incomplete statement or unbalanced delimiters
8 errors
No code generated
--
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5706
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Herencias

Mensaje por jfgimenez »

José,
> Aprovechando el post que le enviaste a Ramon, probé el ejemplo que
> publicaste y sale el error que adjunto.
perdona, lo he escrito "al vuelo" y no he caido en ese pequeño detalle. Para
compilar con [x]Harbour sólo, tienes que poner, al principio del .prg:
#include "hbclass.ch"
Y ya está.
--
Un saludo,
José F. Giménez
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
zeasoftware
Mensajes: 1831
Registrado: Mar Oct 11, 2005 9:53 am

Herencias

Mensaje por zeasoftware »

si, la cosa es ke en casa no tengo internet por ahora, y hago los mensajes
mientras trabajo en xailer, y cuando voy con un cliente ke le tengo
compartida su linea al conectarme recojo los mensajes y pues se cargan los
ke tengo pendientes.
Saludos.
PD.: Keremos una navidad feliz, ya esta el pre-release?!!!, jejejejeje,
perdon, jojojojojojo
Responder