Valor por defecto en una DATA de una clase

Valor por defecto en una DATA de una clase

Postby Carlos Mora » Tue Sep 08, 2015 1:06 pm

Dadas las siguientes clases
Code: Select all  Expand view  RUN
   CLASS TClassA
       DATA uVar INIT 'X'
       METHOD New() CONSTRUCTOR
    ENDCLASS

    ..

    CLASS TClassB FROM TClassA
    ENDCLASS


en las que TClassB hereda todo incluyendo el constructor.

Como cambiar el valor por defecto de uVar en la clase TClassB sin reescribir el constructor?
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Valor por defecto en una DATA de una clase

Postby cnavarro » Tue Sep 08, 2015 1:15 pm

Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6552
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Valor por defecto en una DATA de una clase

Postby Antonio Linares » Tue Sep 08, 2015 5:12 pm

Carlos,

Has probado así ?

Code: Select all  Expand view  RUN
CLASS TClassA
       DATA uVar INIT 'X'
       METHOD New() CONSTRUCTOR
    ENDCLASS

    ..

    CLASS TClassB FROM TClassA
       DATA uVar INIT 'Y'
    ENDCLASS
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42203
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Valor por defecto en una DATA de una clase

Postby Carlos Mora » Wed Sep 09, 2015 10:08 am

Cristobal,
otra cosa más de Harbour que descubrimos! Gracias por la referencia. Pensé que la funcionalidad del 'init' era la del constructor. De todas maneras el plan era no reescribir el constructor, ni su equivalente.
He puesto un ejemplo y al parecer no funciona... Algo debo haberme perdido...

Antonio,
tu idea es la que tuve al principio, pero creo que de esa manera la nueva data oculta la data original, 'desperdiciando' un slot de la variable original.
Funciona, es la que voy a usar hasta que encuentre una mejor.

Lo que comento se puede probar con este código:

Code: Select all  Expand view  RUN

#include "hbclass.ch"
CLASS TClassA
    DATA uVar INIT 'X'
    METHOD New() CONSTRUCTOR
    METHOD Init()
ENDCLASS

METHOD New() CLASS TClassA
RETURN Self

METHOD Init() CLASS TClassA
   ::uVar := 'Z'
RETURN NIL

CLASS TClassB FROM TClassA
    DATA uVar INIT 'Y'
ENDCLASS
 
FUNCTION Main()
   LOCAL tValue, dValue, aStruct
   LOCAL a:= TClassA():New()
   LOCAL b:= TClassB():New()
   
   ? Len(a), Len(b), a:uVar, b:uVar  // 1, 2, X , Y (TClassA No llama automáticamente a Init !!!!)
   
   Inkey(0)
   
   QUIT
   
   


La alternativa de reescribir el constructor no es tan mala con el uso de '...'

Code: Select all  Expand view  RUN

#include "hbclass.ch"
CLASS TClassA
    DATA uVar INIT 'X'
    METHOD New() CONSTRUCTOR
    METHOD Init()
ENDCLASS

METHOD New() CLASS TClassA
RETURN Self

METHOD Init() CLASS TClassA
   ::uVar := 'Z'
RETURN NIL

CLASS TClassB FROM TClassA
    METHOD New() CONSTRUCTOR
ENDCLASS

METHOD New(...) CLASS TClassB
   ::Super:New(...)
   ::uVar := 'Y'
RETURN Self

 
FUNCTION Main()
   LOCAL tValue, dValue, aStruct
   LOCAL a:= TClassA():New()
   LOCAL b:= TClassB():New()
   
   ? Len(a), Len(b), a:uVar, b:uVar
   
   Inkey(0)
   
   QUIT
   

 
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Valor por defecto en una DATA de una clase

Postby Antonio Linares » Wed Sep 09, 2015 5:38 pm

Carlos,

Yo creo que no desperdicia un "slot" sino que lo reemplaza, por lo que es una buena solución :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42203
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Valor por defecto en una DATA de una clase

Postby Carlos Mora » Wed Sep 09, 2015 6:19 pm

Antonio,
Te confirmo que lo desperdicia, el código que subí es un ejemplo completo, al hacer Len() se ve claramente.

Un saludo
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Valor por defecto en una DATA de una clase

Postby cnavarro » Wed Sep 09, 2015 6:56 pm

Carlos Mora wrote:Antonio,
Te confirmo que lo desperdicia, el código que subí es un ejemplo completo, al hacer Len() se ve claramente.

Un saludo


Carlos, no estoy seguro de haberte entendido bien, pero .....

Code: Select all  Expand view  RUN


#include "fivewin.ch"
#include "hbclass.ch"
#include "c:\harbour\contrib\xhb\xhbcls.ch"

CLASS TClassA
    DATA uVar INIT 'X'
    //METHOD New() CONSTRUCTOR
    METHOD Init( uV )
    METHOD InitClass( uV )
ENDCLASS

/*
METHOD New() CLASS TClassA
RETURN Self
*/


METHOD Init( uV ) CLASS TClassA
   ? "Init", uV
   if !empty( uV )
   ::uVar := uV
   endif
RETURN Self

METHOD InitClass( uV ) CLASS TClassA
   ? "InitClass", uV
   if !empty( uV )
   ::uVar := uV
   endif
RETURN Self

FUNCTION Main()
   Local Self
   LOCAL tValue, dValue, aStruct
   LOCAL a:= TClassA():Init() //New()
   LOCAL b
   
   ? Len(a), a:uVar
   EXTEND CLASS TClassA WITH DATA uVar
   b:= TClassA():New( "H" ) //New()
   ? Len(b), b:uVar
   
Return nil

 
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6552
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Valor por defecto en una DATA de una clase

Postby Carlos Mora » Wed Sep 09, 2015 8:23 pm

Cristobal,
El override se debe hacer en una subclase, no en la misma.

Respecto del metodo Init, solo funciona si NO DECLARAS UN CONSTRUCTOR New. Cuando en el blog de Rafa lei que Init se ejecutaba siempre, pensé que sucedia siempre, como si fuese un método Initiate de los controles de FW, pero digamos que en el ejemplo que subiste Init es el constructor por defecto, pero condicionado a que no se declare un constructor.

Lo de Len debe compararse con dos clases, prueba el código que subí. En la subclase redefino la variable, y el Len del objeto queda en 2.
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Valor por defecto en una DATA de una clase

Postby Carlos Mora » Thu Sep 10, 2015 6:52 am

Buenos días gente,

acabo de hacer una pequeña modificación al ejemplo que ayuda a ver que al redeclarar una variable esta se pierde.

Code: Select all  Expand view  RUN

    #include "hbclass.ch"
    CLASS TClassA
        DATA uVar INIT 'X'
        METHOD New() CONSTRUCTOR
        METHOD Init()
    ENDCLASS

    METHOD New() CLASS TClassA
    RETURN Self

    METHOD Init() CLASS TClassA
       ::uVar := 'Z'
    RETURN NIL

    CLASS TClassB FROM TClassA
        DATA uVar INIT 'Y'
    ENDCLASS
     
    FUNCTION Main()
       LOCAL tValue, dValue, aStruct
       LOCAL a:= TClassA():New()
       LOCAL b:= TClassB():New()
       
       ? Len(a), Len(b), a:uVar, b:uVar, b[1], b[2]  // 1, 2, X , Y, X, Y
       
       Inkey(0)
       
       QUIT
   RETURN NIL      
 


Fijaros que b[1] == 'X' y b[2] == 'Y'. Cosillas de los objetos de Harbour :)

Voy a tener que hacer lo que estaba evitando: mirar el código fuente a ver si me entero como cambiar el valor por defecto, :(

Gracias por las respuestas.
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Valor por defecto en una DATA de una clase

Postby Antonio Linares » Thu Sep 10, 2015 7:14 am

Carlos,

Tienes razón, si el array del objeto se incrementa entonces es que no se reescribe la DATA
aunque en cierto modo es lógico, pues así podríamos acceder a la DATA de su Super.

De todas formas, el consumo de memoria para eso es mínimo
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42203
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Valor por defecto en una DATA de una clase

Postby xmanuel » Thu Sep 10, 2015 7:41 am

Hola Carlos.
No es bueno definir new e init en la misma clase. Como bien has dicho init se llama si no existe un constructor concreto.
Tal vez una solución sería esta:

Code: Select all  Expand view  RUN

 #include "hbclass.ch"
    CLASS TClassA
        DATA uVar INIT 'X'
        METHOD New() CONSTRUCTOR
        METHOD Init()
    ENDCLASS

    METHOD New() CLASS TClassA
         if ::className() == "TCLASSB"
             ::uVar := "Y"
        endif
    RETURN Self

    METHOD Init() CLASS TClassA
       ::uVar := 'Z'
    RETURN NIL

    CLASS TClassB FROM TClassA
    ENDCLASS
 


No lo he probado pero por ahí pueden ir los tiros para no usar un nuevo slot ;-) si defines la misma data en una clase heredada siempre reserva otro slot nuevo para poder acceder a la data super independientemente. Por otro lado no me mola mucho usar init y new en la misma clase, manías mías, :-)
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 763
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Valor por defecto en una DATA de una clase

Postby hmpaquito » Thu Sep 10, 2015 12:28 pm

Colegas,

Yo lo haria creando un nuevo metodo que solamente se declararia en aquellas clases que necesitaran variar el valor inicial de alguna data.

Code: Select all  Expand view  RUN

CLASS TClassA()
   DATA cData INIT "A"

   METHOD New()
   METHOD InitValores() VIRTUAL
ENDCLASS

METHOD New()
::InitValores()
RETURN NIL


CLASS TClassB()
   METHOD InitValores()
ENDCLASS
   
METHOD InitValores()
   cData:= "B"
RETURN NIL
 


Mis dos centimos, de euro.
hmpaquito
 
Posts: 1482
Joined: Thu Oct 30, 2008 2:37 pm

Re: Valor por defecto en una DATA de una clase

Postby xmanuel » Thu Sep 10, 2015 7:51 pm

Creo que lo que quiere Carlos es no utilizar un slot nuevo para la "misma" DATA y no tener que redefinir el constructor...
Redefiniendo el constructor new no hay problema, basta con no inicializar cData en la definicióm de la clase y asignarle un valor en la implementación de la clase:
Code: Select all  Expand view  RUN

 #include "hbclass.ch"
    CLASS TClassA
        DATA uVar
        METHOD New() CONSTRUCTOR
    ENDCLASS

    METHOD New() CLASS TClassA
       ::uVar := 'A'
    RETURN Self

    CLASS TClassB FROM TClassA
        METHOD New() CONSTRUCTOR
    ENDCLASS

    METHOD New() CLASS TClassA
       ::uVar := 'B'
    RETURN Self
 


Pero Carlos no quiere redefinir new

No es así Carlos?
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 763
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Valor por defecto en una DATA de una clase

Postby Carlos Mora » Fri Sep 11, 2015 6:51 am

Manu,
exactamente eso es lo que busco. Estoy extendiendo algunas clases de FW, cuyos constructores son bastante complejos, y como ademas son clases de un proveedor que las actualiza, se trata de modificar lo mínimo imprescindible en los métodos originales. En esas extensiones algunos valores por defecto no son los ideales, y a eso se resume el problema. Cristobal me pasó el enlace a un post de Rafa donde hablabla de que Init e InitClass se llamaban automáticamente, y me pareció interesante pero no es exactamente la cuestión del hilo.
Para este caso en particular, teniendo constructores con tantos parámetros, puedo sacar provecho de lo que se habló en otro hilo respecto del operador '...':
Code: Select all  Expand view  RUN

METHOD New(...) CLASS TClassB
   ::Super:New(...) // pasar todos los parametros al método New de TClassA
   ::uVar:= 'Y'
RETURN Self

 


Pro cierto, tu que estás más en eso de C seguro que me puedes ayudar: ¿Como hago para modificar una variable string pasada por referencia en C? La idea es modificar la cadena, sin crear un buffer para copiar y modificar (como lo hace, por ejemplo, stuff) y retornar el valor.

Un saludo
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Valor por defecto en una DATA de una clase

Postby xmanuel » Sat Sep 12, 2015 4:38 pm

Puedes intertarlo así:

Code: Select all  Expand view  RUN


    local cSql := "hola estoy aqui sin cambiar"
    cls
    ? cSql
    cambia( @cSql )
    ? cSql
    Inkey( 100 )

 

Y en C
Code: Select all  Expand view  RUN


HB_FUNC( CAMBIA )
{
    PHB_ITEM i = hb_param( 1, HB_IT_STRING );
   
    hb_itemPutC( i, "Esto es una prueba nada mas xxxxxxxxxxxxxxxxxxxxxxxxxx" );
}

 


No sé si es eso lo que quieres ;-)
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 763
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Next

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 15 guests