FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Valor por defecto en una DATA de una clase
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Valor por defecto en una DATA de una clase
Posted: Tue Sep 08, 2015 01:06 PM
Dadas las siguientes clases
Code (fw): Select all Collapse
    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"
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Valor por defecto en una DATA de una clase
Posted: Tue Sep 08, 2015 01: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
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Valor por defecto en una DATA de una clase
Posted: Tue Sep 08, 2015 05:12 PM
Carlos,

Has probado así ?

Code (fw): Select all Collapse
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
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Valor por defecto en una DATA de una clase
Posted: 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 (fw): Select all Collapse
#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 (fw): Select all Collapse
#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"
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Valor por defecto en una DATA de una clase
Posted: Wed Sep 09, 2015 05: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
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Valor por defecto en una DATA de una clase
Posted: Wed Sep 09, 2015 06: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"
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Valor por defecto en una DATA de una clase
Posted: Wed Sep 09, 2015 06: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 (fw): Select all Collapse
#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
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Valor por defecto en una DATA de una clase
Posted: Wed Sep 09, 2015 08: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"
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Valor por defecto en una DATA de una clase
Posted: Thu Sep 10, 2015 06: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 (fw): Select all Collapse
    #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"
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Valor por defecto en una DATA de una clase
Posted: Thu Sep 10, 2015 07: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
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Valor por defecto en una DATA de una clase
Posted: Thu Sep 10, 2015 07: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 (fw): Select all Collapse
 #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
Posts: 1515
Joined: Thu Oct 30, 2008 02:37 PM
Re: Valor por defecto en una DATA de una clase
Posted: 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 (fw): Select all Collapse
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.
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Valor por defecto en una DATA de una clase
Posted: Thu Sep 10, 2015 07: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 (fw): Select all Collapse
 #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
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Valor por defecto en una DATA de una clase
Posted: Fri Sep 11, 2015 06: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 (fw): Select all Collapse
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"
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Valor por defecto en una DATA de una clase
Posted: Sat Sep 12, 2015 04:38 PM
Puedes intertarlo así:

Code (fw): Select all Collapse
    local cSql := "hola estoy aqui sin cambiar"
    cls
    ? cSql
    cambia( @cSql )
    ? cSql
    Inkey( 100 )

Y en C
Code (fw): Select all Collapse
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