Aunque no comparto la idea de antonio en que la herencia multiple genera mas problemas que soluciones, si estoy de acuerdo en que muchas veces es mejor manejar clases contenedoras como lo dice antonio, como por ejemplo, lo es tu caso. No creo que sea buena idea tener que estar modificando la clase de esa manera para simular la herencia multiple, lo mas seguro es que en tu caso no tengas problemas, porque no creo que utilices mas de un tipo de clase (herencia) en el programa ¿pero que pasa si tuvieras que utilizar 2 o 3?
Por otro lado, yo utilizo eso que haces para modificar las clases de fivewin, por ejemplo, no se si has visto el editor que estoy haciendo, maneja barra de mensajes y pestañas para indicar los archivos abiertos, ambos como barras inferiores, es mas, si abres demasiados archivos puedes tener 2 o mas barras de tabs, algo que no permite de manera nativa fivewin ¿pero cual es el problema? bueno, pues que lo que hice fue modificar algunos métodos y variables de instancia, no solo para eso que comento, sino para otras operaciones del programa, con las funciones que indicas, y si tengo algún problema, por ejemplo un mensaje de error al inicio del programa, o por hacer pruebas creo una ventana antes de la ventana principal, me causa errores como si no funcionara bien el llamado a las funciones para modificar las clases.
No se a que se deba, y claro, el tipo de clases que modifico (window, control, y una que otra mas de algun control en especifico) son totalmente distintas a la que estas modificando tu, pero supongo que podrías llegar a tener algún tipo de complicación como la que me ocurre a mi.
En tu caso, te recomendaría algo mas parecido a lo siguiente (si es que utilizas xharbour, con harbour tendrías que manejar (...) como en el ejemplo de antonio).
- Code: Select all Expand view
CLASS tData FROM TDataBase
data oDatabase
method new
error handler onError
ENDCLASS
METHOD new( ... ) CLASS tData
local aParams := hb_aParams()
local cType := aParams[ 1 ]
aDel( aParams, 1, .t. )
do case
case cType == "database"
::oData = TDataBase():New( aParams )
case cType == "rs"
::oData = TRS():New( aParams )
case cType == "mysql"
::oData = TMySQL():New( aParams )
endcase
return self
METHOD onError( ... ) CLASS TData
return hb_execFromArray( oDatabase, __getMessage(), hb_aParams() )
De hecho, este ejemplo que te estoy dando realmente lo uso, no para manejar archivos, sino en clases que manejan browse, y también tengo algo parecido a lo que quieres manejar, por ejemplo, tengo estos dos comandos
DEFINE WINDOW BROWSE oWnd ARRAY aDatos HEAD "col1", "col2", "col3"
y
DEFINE WINDOW XBROWSE oWnd ARRAY aDatos HEAD "col1", "col2", "col3" AUTOCOLS
con esas dos creo dos ventanas con un browse, uno de la clase qWBrowse() (hereda de tWbrowse() ) y el otro de qXBrowse() (hereda de tXBrowse() ), ambas heredan de las mismas clases, pero manejan un browse distinto, y en cada una cargo el browse correspondiente, por ejemplo, eso quiere decir que si en algun problema utilizo el segundo comando y no el primero, no se carga en memoria twbrowse porque no hago referencia en ningún lado a ese fuente, pero con solamente escribir
oWnd:goTop()
le estoy diciendo al browse que se vaya al inicio del archivo.
Y en estas clases que te comento hago uso de ambos metodos, tanto uso herencias multiples, como clase contenedora, y la clase contenida es el browse, al cual tengo accesos con el capturador de error como te lo muestro en el ejemplo.