Vous êtes sur la page 1sur 18

INTRODUCCIN A LA POO EN VISUAL FOXPRO: CONCEPTOS BSICOS (I)

Con este artculo empezamos una pequea serie que nos acercar a la Programacin
Orientada a Objeto (POO) en Visual FoxPro. En este, el primero, haremos una descripcin de
los conceptos bsicos sobre los que se sustenta la POO a fin de introducirnos en es ta forma de
programar.
Si Vd. es nuevo en esto de la POO es posible que en algunos momentos se sienta perdido. No
se preocupe, es normal. La orientacin a objeto tiene un gran nmero de conceptos
interrelacionados, por ello cuando describimos uno de forma separada parece carece r de
sentido. No dude en releer el texto una y otra vez, de esa forma conseguir tener una visin de
conjunto.
Si por el contrario ya lleva algn tiempo aplicando estas tcnicas lo que le interesa realmente
es la implementacin que de estas tcnicas de programacin hace Visual Foxpro (VFP), en
parte podr ver algunas de sus caractersticas en este artculo, pero e s realmente en los
prximos donde se desarrollar toda la potencia de VFP. Hemos intentado en todo momento
ser rigurosos, pero espero que disculpe que en algunas ocasiones se haga una descripcin
poco formal de las caractersticas de la POO a fin de facilitar la compresin.
Si ya conoce algunas de las caractersticas de VFP sabr que es posible realizar POO casi sin
darse cuenta, pero en este artculo haremos hincapi en los entresijos de este tipo de
programacin desde la codificacin ms tradicional, a fin de saber perfectamente lo que
estamos haciendo en cada momento. En prximos artculos describiremos la POO cuando
utilizamos Form Designer, el generador de pantallas, o Class Designer, la herramienta visual
para definicin de clases, as como el manejo de herramientas de apoyo como el Class
Browser.

NO ES TAN DIFCIL
Est de moda hablar de POO, y no es nuevo este concepto, pero es ahora cuando se est
generalizando su uso. Esta moda ha provocado alguna confusin, muchas herramientas han
dicho estar orientadas a objeto sin serlo, otras han realizado implementaciones muy extraas,
y algunas, como VFP, han sabido mantener un equilibrio y una buena implementacin, por lo
que son verdaderamente recomendables para desarrollar con este nuevo sistema de
programacin.
Quizs uno de los problemas a la hora de afrontar por primera vez la POO, estriba en el temor
que puede producir tantos y tantos nuevos conceptos que se ciernen sobre nosotros. Lo cierto
es que la POO no es tan fiera como la pintan, pero en la medida que cambia algo nuestra
forma de pensar los programas, sus componentes y el modo que se relacionan entre si,
requiere un cierto esfuerzo.
Los que llevan aos en esto de la programacin recuerdan lo difcil y extrao que fue el paso
de la programacin lineal (con goto) a la programacin estructurada (con call), ahora toca el
paso de la programacin estructurada a la POO. La POO viene a completar algunas de las
lagunas de la programacin estructurada, como esta vino a solucionar algunos de los
problemas de la programacin lineal. No es la soluciona a todos nuestros problemas, pero s
facilita nuestra labor de programacin y mantenimiento.


OBJETIVOS DE LA POO
La POO intenta ser un mejor sistema para el desarrollo de aplicaciones. Como toda tcnica de
programacin si se hace mal puede ser desastrosa -pensemos los los que se pueden provocar
si aplicamos mal la programacin estructurada- pero es un mejor sistema de desarrollo.
Una de las primeras mejoras que obtenemos por el uso de la POO es el permitir afrontar
programas ms complejos y de mayor tamao con menos esfuerzo. El hecho de trabajar con
pequeos elementos bien definidos, como son los objetos, nos permite aislar cada
componente de la aplicacin del resto y de esa forma aprovechar en mayor medida nuestro
esfuerzo.
Una vez adiestrados en las nuevas tcnicas de orientacin a objeto obtendremos tambin una
mejora considerable en nuestro rendimiento de desarrollo. Las grandes facilidades para el
reaprovechamiento del cdigo que nos ofrece la orientacin a objeto harn que desarrollemos
con mayor velocidad, pero manteniendo unos buenos niveles de calidad.
La reutilizacin de cdigo en la POO nos otorga una gran flexibilidad. La existencia de la
herencia permite modificar las caractersticas que necesitemos de una clase de objeto con
seguridad de no alterar las especificaciones del mismo y aprovechan do todo el desarrollo
realizado en el mismo.
El mantenimiento de aplicaciones se ha visto como uno de los grandes problemas de la
programacin actual. Con las tcnicas de POO es ms sencillo realizar este mantenimiento. Los
objetos son elementos de pequeo tamao, bien definidos, y por lo tan to ms fciles de
mantener. Adems la existencia de la herencia nos va a asegurar que la modificacin de
algunas caractersticas de la clase no van ha afectar a los desarrollos ya terminados.
La definicin correcta de los objetos permitir tener una mejor estructuracin de nuestros
programas. Con la POO se tiene un acercamiento ms natural a los problemas y por lo tanto
los anlisis de aplicaciones orientadas a objeto tienen un acercamiento a la realidad mucho
ms completa que con la programacin estructurada. Esto no quiere decir que al principio no
cueste un poco realizar este tipo de anlisis, pero una vez adquirida las nuevas tcnicas, es
mucho ms sencillo.
La POO es muy fcilmente compresible en entornos grficos, pues el hecho de que estos
entornos manejen objetos grficos hace muy recomendable este tipo de programacin. Pero
debemos tener claro que es totalmente posible realizar POO en entornos de tipo carcter y es
posible programar entornos grficos sin POO.

NO TODO SON VENTAJAS.
Tampoco podemos decir que todo sean facilidades. Por una parte la POO nos va ha obligar a
cambiar nuestra forma de pensar los programas y por lo tanto es necesario un tiempo para
que las nuevas tcnicas se nos hagan habituales y automticamente nos salga programar de
esta forma.
No basta con dominar estas tcnicas para que alcancemos las mejores cotas de productividad,
posiblemente sea necesario elaborarnos unas buenas libreras de clases. Para ello es
conveniente desarrollar un par de aplicaciones bajo esta tcnica para darnos cuenta de que es
lo que realmente es factible de ser reutilizado y de esa forma organizar nuestras propias
libreras de clases.
La depuracin de cdigo orientado a objeto es algo ms compleja que la depuracin de cdigo
estructurado. Esto no quiere decir que nuestro cdigo va a ser peor o va ha tener ms errores,
pero s es cierto que en el caso de producirse un error deberemos re correr todo el rbol de
herencia para encontrarlo, algo que en programacin estructurada no tenemos que hacer.
Pero en general, podemos decir que los inconvenientes son realmente menores que las
ventajas, y por lo tanto es realmente recomendable el desarrollo con POO.

ELEMENTOS DE LA POO
Vamos a hacer un repaso de los distintos elementos que componen la POO, y como cada uno
de ellos es implementado en VFP. En algunos momentos es posible que no entienda algunos
de los conceptos, no se preocupe, poco a poco intentaremos aclarar todo este entramado de
conceptos y sintaxis. Clase y Objeto. Son los dos primeros elementos de la POO. Se puede decir
que la clase es la generalizacin de los objetos y los objetos son la concrecin de la clase, aun
cuando parezca un galimatas.
Se suelen poner ejemplos bastante filosficos para describir la relacin entre el objeto y la
clase (variando segn sea el autor idealista o empirista). Podemos decir que existen un objeto
Pedro, otro Antonio y otro Luisa. Todos estos objetos tienen elementos en comn y por ello
decimos que son de la clase persona. De la misma forma otros dicen que tenemos una idea
clara de lo que es ser una persona y luego somos capaces de distinguir hombres concretos.
Para poner otro tipo de ejemplo podemos observar los botones de un entorno grfico. Todos
sabemos como es un botn en un entorno grfico, si bien cada botn es diferente de los
dems, todos se parecen y por lo tanto podemos decir que la clase botn es la generalizacin
de las propiedades y comportamientos de todos los botones de los entorno grficos.
Definir una clase. Las clases son la descripcin de los elementos comunes de los objetos que
generalizan. As las clases se definen y pueden ser usadas para crear innumerables objetos de
este tipo. Para definir una clase utilizaremos una sencilla sintaxis de VFP. Vamos a empezar
definiendo una clase denominada Persona. Es una clase vaca, pero nos sirve para comenzar:
DEFINE CLASS Persona AS CUSTOM
ENDDEFINE
Para poder utilizar esta definicin debemos incluirla en un fichero .PRG y cargado con SET
PROCEDURE TO o bien incluirla al final de nuestro fichero .PRG.
Crear un objeto. Ya podemos crear objetos basado en esta clase, para ello utilizamos la
siguiente expresin:
oPersona1 = CREATEOBJECT( "Persona" )
oPersona2 = CREATEOBJECT( "Persona" )
Debemos tener clara la diferencia entre clase y objeto. La clase es una plantilla, donde
definimos las caractersticas de cada uno de los objetos. Los objetos que hemos creado,
oPersona1 y oPersona2, comparten la plantilla que con la que se han creado, la clase Persona,
pero son diferentes entre si.

Borrar un objeto. Los objetos se asemejan a las variables en cuanto a que pueden declararse
como LOCAL, PRIVATE o PUBLIC. Esta es la nica similitud que tienen las variables y los objetos,
pero es una caracterstica muy importante.
Por defecto, los objetos son de tipo PRIVATE y por lo tanto existirn mientras se ejecute el
programa que los cre. Una vez salgamos de este programa el objeto se borrar
automticamente. El objeto puede ser usado en el programa que lo cre y en todos lo
programas llamados desde l.
Si declaramos el objeto como LOCAL el objeto persistir hasta la salida del programa que lo
cre, pero los programas que sean llamados desde el programa de creacin no podrn hacer
uso de este objeto, pues permanece oculto par a ellos, evitando as posibles problemas con los
nombres de los objetos.
Al declarar un objeto como PUBLIC estamos indicando que permanezca hasta que lo borremos
explcitamente o salgamos de VFP. Este objeto podr ser utilizado por cualquier programa
desde el momento que es creado hasta que sea borrado.
Para borrar un objeto de forma explcita debemos hacer uso del comando RELEASE. Podemos
borrar de forma explcita no solo los objetos pblicos, sino tambin los locales y privados.
Veamos un ejemplo muy simple de creacin de un objeto pblico y su destruccin:
PUBLIC oPrueba
oPrueba = CREATEOBJECT( "Persona" )
...
RELEASE oPrueba
Encapsulacin. Aunque parece un termino extrao, es muy habitual en POO. Hace referencia a
la capacidad de los objetos para incluir dentro de si tanto datos como acciones. Las clases de
distinguen unas de otras justamente por tener unos datos y acciones que las diferencian. Los
objetos de una misma clase se diferencian entre si por tener datos diferentes.
Los datos que caracterizan a una clase se denominan propiedades y sus acciones (o programas)
se denominan mtodos. Se dice por lo tanto que la clase encapsula mtodos y propiedades, es
decir, que agrupa dentro si tanto mtodos como propiedades.
Las propiedades y mtodos de una clase se denominan habitualmente propiedades y mtodos
miembro.
Veamos poco a poco estos nuevos conceptos.
Propiedades. Como hemos dicho, las propiedades son los datos que manejan las clases. Estas
propiedades se declaran en la definicin de la clase y permanecen en todo momento asociados
a los objetos creados bajo esa clase.
Para verlo con ms claridad vamos a dar contenido a esta definicin de la clase Persona que
iniciamos hace un momento. Para ello debemos estudiar que propiedades posee este tipo de
objeto. Podemos decir que todas la personas tienen un nombre, unos apellidos y una fecha de
nacimiento. Hay muchas otras propiedades para una clase de este tipo, pero empecemos con
estas. La implementacin en VFP se hara de la siguiente manera:
DEFINE CLASS persona AS CUSTOM
cNombre = ""
cApellidos = ""
dFechaNacimiento = {}
ENDDEFINE
En nuestra definicin de clase declaramos las propiedades con unos valores iniciales, que
pueden ser de cualquiera de los tipos de datos definidos en VFP. Por ejemplo, cNombre y
cApellidos los hemos inicializado como una cadena vaca y dFechaNacimiento como una fecha
tambin vaca, pero pueden ser numricos, datetime o de cualquier otro tipo.
Tambin podramos haber definido las propiedades con cualquier otro tipo de valor por
defecto: una texto o una fecha en concreto, de esta forma, al crear un objeto ya tendra este
valor la propiedad.
Por ejemplo podramos ampliar la definicin de la clase incluyendo una propiedad denominada
cEstadoCivil que por defecto fuera la cadena Soltero.

DEFINE CLASS persona AS CUSTOM
cNombre = ""
cApellidos = ""
dFechaNacimiento = {}
cEstadoCivil = "Soltero"
ENDDEFINE
Una vez creado un objeto, si quedemos dar valores a cada una de sus propiedades haremos
uso de operador punto. Para ello pondremos el nombre del objeto, un punto y el nombre de la
propiedad:
oPersona1 = CREATEOBJECT( "persona" )
oPersona1.cNombre = "Mara"
oPersona1.cApellidos = "Prez Gonzlez"
oPersona1.dFechaNacimiento = {20-10-75}

oPersona2 = CREATEOBJECT( "persona" )
oPersona2.cNombre = "Pedro"
oPersona1.cApellidos = "Jimnez Nieto "
oPersona2.dFechaNacimiento = {04-12-69}
oPersona2.cEstadoCivil = "Casado"
Si, como en este caso, vamos a dar valores a muchas propiedades de un objeto podemos
utilizar la sintaxis abreviada, de la forma siguiente:
WITH oPersona2
.cNombre = "Pedro"
.cApellidos = "Jimnez Nieto "
.dFechaNacimiento = {04-12-69}
.cEstadoCivil = "Casado"
ENDWITH
Desde ese momento podemos hacer uso de estas propiedades, usando tambin el operador
punto:
WAIT WIND oPersona1.cNombre
WAIT WIND oPersona2.cNombre
Como decamos, las propiedades estn asociadas a cada objeto, de esta forma el valor de la
propiedad cNombre es diferente entre los objetos oPersona1 y oPersona2, aun cuando en la
definicin de la clase hubiramos otorgado un va lor por defecto a esta propiedad. Es
importante tener clara esta diferencia. Las propiedades se declaran en la definicin de la clase,
pero los valores de las propiedades pueden ser diferentes para cada uno de los objetos de esta
clase.

Mtodos. El otro elemento caracterstico de una clase son los mtodos. Los mtodos son
acciones que pueden realizar los objetos, es decir, son funciones o procedimientos asociados a
este tipo objeto.
En el caso de las personas podemos decir que pueden nacer, morir, casarse, tener hijos, etc...
Para dar un primer ejemplo de esto veamos uno de sus mtodos :

DEFINE CLASS persona AS CUSTOM
cNombre = ""
cApellidos = ""
dFechaNacimiento = {}
cEstadoCivil = "Soltero"

PROCEDURE Nacer
LPARAMETER cNombre, ;
cApellidos, ;
dFecha
This.cNombre = cNombre
This.cApellidos = cApellidos
This.dFechaNacimiento = dFecha
ENDPROC

ENDDEFINE

En este mtodo damos valor a tres propiedades del objeto a partir de los parmetros que se
nos han pasado. Quizs sea todava poco evidente este cdigo, pero poco a poco iremos
entendindolo.
En primer lugar debemos diferenciar entre los parmetros de este mtodo y las propiedades.
Los parmetros son variables y se perdern al finalizar la ejecucin del mtodo. Las
propiedades, que son la que empiezan con la sintaxis This., permanecen mientras dure la
existencia del objeto.
Por otra parte, este procedimiento, denominado Nacer, se diferencia de los procedimientos
que estamos acostumbrados a escribir en que slo es llamable asociado a un objeto de la clase
Persona y no puede ser invocado de forma independiente. Esta es una de las grandes
diferencias entre la programacin estructurada y la POO.

Mensajes. Cuando llamamos a un mtodo de un objeto se dice que estamos enviando un
mensaje al objeto para que realice una determinada accin. As cuando enviamos un mensaje
de nacer a un objeto persona estamos ejecutando el mtodo correspondiente:

oPersona1 = CREATEOBJECT( "Persona" )
oPersona1.Nacer( "Mara", ;
"Prez Gonzlez", ;
{20-10-75} )
? oPersona1.cNombre
? oPersona1.cApellidos

OPERADOR THIS.
Vemos dentro del cdigo del mtodo Nacer que hemos utilizado una extraa sintaxis, algo
como THIS. Decamos al principio que la clase es una plantilla y cuando definimos un mtodo
dentro de esta plantilla que es la clase no sabemos cual ser el nombre del objeto que utilizar
este mtodo, por eso, cuando vamos a utilizar una propiedad o un mtodo de la clase,
debemos anteponer al operador punto el operador This, para indicar que se trataran las
propiedades del objeto que recibe el mensaje, es decir, que ha sido invocado, y no para otro.
Decamos que las propiedades mantienen valores diferentes para cada uno de los objetos,
pero los mtodos comparten su cdigo entre todos los objetos de una clase. Un mtodo vara
en la medida que las propiedades del objeto que lo llama son diferentes, por ello es tan
importante el operador This.
De esta forma cuando ejecutamos:
oPersona1.Nacer( "Mara", ;
"Prez Gonzlez", ;
{20-10-75} )
el cdigo del mtodo Nacer asocia el primer parmetro, denominado cNombre, a la propiedad
cNombre del objeto que recibe el mensaje. As This.cNombre es una propiedad del objeto y
cNombre es una variable que cor responde al primer parmetro del mtodo invocado en el
mensaje.

PROCEDURE Nacer
LPARAMAMETER cNombre, ;
cApellidos, ;
cFecha

This.cNombre = cNombre
...

ENDPROC

Ocultacin. Una de las mejoras que implementa la POO, es la posibilidad de limitar el acceso a
determinadas propiedades o mtodos. Con ello conseguimos que la utilizacin de la clase se
haga de forma ordenada.
Las propiedades o mtodos protegidos slo son utilizables desde los mtodos pertenecientes a
esta clase y no pueden usarse directamente por otros programas. Vamos con un ejemplo:

DEFINE CLASS Nivel AS CUSTOM

PROTECTED nContador
nContador = 0

PROCEDURE Mas
LPARAMETER nCantidad
This.nContador = This.nContador ;
+ nCantidad
ENDPROC

PROCEDURE Menos
LPARAMETER nCantidad
This.nContador = This.nContador ;
- nCantidad
ENDPROC

PROCEDURE Ver
RETURN This.nContador
ENDPROC

ENDDEFINE
Esta clase define un interface por medio de los mtodos Mas, Menos y Ver. Si intentamos
modificar el valor de nContador de forma directa nos dar un error, pues esta propiedad est
protegida.

oTemperatura = CREATEOBJECT( "Nivel" )

oTemperatura.Mas ( 10 )
? oTemperatura.Ver()
oTemperatura.Menos ( 3 )
? oTemperatura.Ver()

* Proboca el Error :
* Property NCONTADOR is not found.
oTemperatura.nContador = 100
Al igual que podemos proteger propiedades, podemos proteger mtodos. De esta forma
podemos definir mtodos que slo sean usado por otros mtodos de la clase y no puedan ser
invocados a partir de los objetos de esta clase. Para ello basta colocar la clus ula PROTECTED
antes de PROCEDURE.

Polimorfismo. Cuando realizamos programacin estructurada debemos tener cuidado de no
llamar con el mismo nombre a dos variables o a dos procedimientos, sin embargo en la POO
podemos llamar a un mtodo o a una propiedad de una clase de igual forma que un mtodo o
propiedad de otra. Esta caracterstica es lo que se denomina polimorfismo. Veamos un
ejemplo con propiedades:

DEFINE CLASS ClaseUno AS CUSTOM
Dato = 1000
ENDDEFINE

DEFINE CLASS ClaseDos AS CUSTOM
Dato = "Hola"
ENDDEFINE
Esto, que puede parecer un problema, es muy sencillo de entender si vemos como los
utilizamos los dos objetos :

Objeto1 = CREATEOBJECT( "ClaseUno" )
Objeto2 = CREATEOBJECT( "ClaseDos" )

? Objeto1.Dato
? Objeto2.Dato
Aun cuando en los dos objetos llaman a una propiedad denominada Dato, en el primer caso
estamos llamando a una propiedad tipo numrica definida en ClaseUno, y el segundo caso
estamos llamado a una propiedad de tipo carcter definida en ClaseDos.
Igual que las propiedades, en el caso de los mtodos tambin es posible el polimorfismo. De
esta forma podemos definir dos mtodos denominados Imprimir, pero que cada uno hace una
cosa bien distinta:

DEFINE CLASS ClaseUno AS CUSTOM
PROCEDURE Imprimir
? "Hola esto es una prueba ..."
ENDPROC
ENDDEFINE

DEFINE CLASS ClaseDos AS CUSTOM
PROCEDURE Imprimir
LIST STATUS
ENDPROC
ENDDEFINE

En VFP no es posible definir dos mtodos o dos propiedades con igual nombre dentro de una
misma clase.
Eventos. Existe una serie de mtodos especiales, que normalmente no se ejecutan por ser
invocados de forma explcita, como los que hemos definido hasta ahora, sino que por
denominarse de una forma determinada son lanzados cuando 'pasa algo', es decir, cuando se
produce un evento. Estos eventos pueden ser un click, el movimiento del ratn, un pulsacin
de tecla, etc..
Los dos primeros eventos que vamos a tratar son los denominados Init y Destroy. El primero se
ejecuta cuando se crea un objeto de esta clase y el segundo cuando se destruye. En otros
lenguajes orientados a objeto estos mtodos son denominados el constructor y el destructor
de la clase, pero el VFP son tratados como eventos. Los eventos Init y Destroy los encontramos
en absolutamente todos los objetos de VFP. Veamos como hacer uso de esta caracterstica
creando dos mtodos con estos nombres:

* Lanzamiento automtico del
* mtodo INIT
oPrueba = CREATEOBJECT( "Eventos" )
...
* Lanzamiento automtico del
* mtodo DESTROY
RELEASE oPrueba

DEFINE CLASS Eventos AS CUSTOM
PROCEDURE Init
? "Creacin del objeto ..."
ENDPROC

PROCEDURE Destroy
? "Destruccin del objeto ..."
ENDPROC
ENDDEFINE
Cada tipo clase tiene unos eventos predefinidos y que no podemos aadir ms. As, por
ejemplo, la clase CUSTOM tiene definidos los eventos Init, Destroy y Error, la clase
COMMANDBUTTOM los eventos Click, Destroy, DragDrop, DragOver, Error, ErrorMessage,
GotFocus, Init, InteractiveChange, KeyPress, LostFocus, Message, MouseDown, MouseMove,
MouseUp, RightClick, UIEnable, Valid, When, etc.. La mayora de estos eventos los veremos en
prximos artculos de forma detallada. De momento quedmonos con el concepto de evento.
Objetos como propiedades. Existe la posibilidad, en algunas clases, de definir objetos como
propiedades miembro. Por ejemplo, podemos querer definir una clase matrimonio con dos
objetos tipo persona. As definiramos:

DEFINE CLASS Matrimonio AS CUSTOM
dFecha = {}
ADD OBJECT Conyuge1 AS Persona
ADD OBJECT Conyuge2 AS Persona
ENDDEFINE
Para poder hacer uso de ellos no tenemos ms que indicar el nombre del objeto miembro. Por
ejemplo:
oPareja1 = CREATEOBJECT( "Matrimonio" )
oPareja1.Conyuge1.Nombre = "Mara"
oPareja2.Conyuge2.Nombre = "Pedro"
No todas las clases admiten que sean definidos objetos como miembros de la misma, slo las
clases denominadas contenedoras, entre la que se encuentra CUSTOM.





Introduccin a la POO en Visual FoxPro : Conceptos
bsicos (y II)
Por razones de espacio se interrumpi en el nmero anterior el relato de los
elementos y conceptos de la programacin orientada a objeto y su implementacin
en Visual FoxPro 3.0. En este artculo continuaremos con esa descripcin.
En el artculo anterior intentamos explicar los conceptos de Clase, Objeto,
Encapsulacin, Propiedad, Mtodo, Mensaje, Operador This, Ocultacin,
Polimorfismo y Evento. Pero dejamos para este artculo uno de los principios
bsicos de la programacin orientada a objeto, la Herencia.
Herencia. La herencia es un mecanismo que nos va a permitir reutilizar nuestro
cdigo de forma fcil y ordenada. Siempre que hemos definido una clase en los
ejemplos anteriores hemos heredado de la clase base CUSTOM. No hemos sido
conscien tes de ello, pero siempre hemos puesto la clusula AS CUSTOM, es decir,
estabamos heredando de la clase CUSTOM. Para verlo ms claramente vamos a crear
una clase llamada Prueba y utilizaremos la orden DISPLAY OBJECT par a ver como
est formado un objeto de esta clase:
oPrueba = CREATEOBJECT( "Prueba" )
DISPLAY OBJECTS

DEFINE CLASS Prueba AS CUSTOM
ENDDEFINE
Podremos obtener una salida de DISPLAY OBJECS similar a la figura 1.
Object: OPRUEBA Priv O PRUEBA

Class Tree:
PRUEBA
CUSTOM

Properties:
BASECLASS C "Custom"
CLASS C "Prueba"
CLASSLIBRARY C "C:\TMP\prueba.FXP"
COMMENT C ""
HEIGHT N 17 ( 17,00000000)
LEFT N 0 ( 0,00000000)
NAME C "Prueba1"
PARENTCLASS C "Custom"
PICTURE C ""
TOP N 0 ( 0,00000000)
WIDTH N 100 ( 100,00000000)

Methods and Events:
ADDOBJECT DESTROY ERROR
INIT REMOVEOBJECT SAVEASCLASS
Podemos observar en primer lugar el objeto se llama OPRUEBA y es de tipo PRUEBA.
En la seccin Class Tree vemos que esta clase tienen un rbol de herencia
compuesto dePRUEBA y CUSTOM. As mismo vemos un buen nmero de propiedades
y algunos mtodos que nosotros no hemos escrito y esto se debe ha que al haber
definido la clase PRUEBA como una clase heredada de la clase CUSTOM hemos
heredado las propiedades y mtodos de esta clase padre.
En VFP siempre es necesario crear una clase heredando de alguna otra. De esta
forma, cualquier clase que creemos tendr siempre algunas propiedades y algunos
mtodos que toda clase de VFP posee. La clase CUSTOM slo posee los mtodos y
propiedades que siempre podremos encontrar en todo objeto, todas las dems
clases predefinidas en VFP (un total de 33) tiene muchas ms propiedades y
mtodos que los descritos aqu, pero siempre tienen estos mtodos y propiedades
bsicos.
Sigamos con los ejemplos de la clase Persona. Definimos en su momento esta
clase, pero ahora nos damos cuenta que debemos hacer una ampliacin. En la
aplicacin necesitamos tratar tambin un caso concreto de persona, los
contribuyentes, pero sabemos que no todas las personas son contribuyentes, pero
todos los contribuyentes son personas. Tras un cierto anlisis concluimos que es
necesaria la herencia para incluyendo nuevos datos y mtodos de la clase
Contribuyente pero manteniendo la integridad y funcionalidad de la clase Persona.
Veamos cmo se hace esta herencia:
* Clase original
DEFINE CLASS persona AS CUSTOM
cNombre = ""
cApellidos = ""
dFechaNacimiento = {}
cEstadoCivil = "Soltero"

PROCEDURE Nacer
LPARAMETER cNombre, ;
cApellidos, ;
dFecha
This.cNombre = cNombre
This.cApellidos = cApellidos
This.dFechaNacimiento = dFecha
ENDPROC
ENDDEFINE

* Clase nueva
DEFINE CLASS Contribuyente AS Persona
cNIF = ""
nBaseImponibe = 0
cRegimenSS = ""
ENDDEFINE
Cuando definamos un objeto de la clase Contribuyente, podremos hacer uso tanto
de las propiedades definidas en su clase como en las definidas en las clases
superiores. As podremos decir:
oContr = CREATEOBJECT( "Contribuyente" )

* Propiedades definidas
* en la clase Persona
oContr.cNombre = "Juan"
oContr.cApellidos = "Lpez Garrido"

* Propiedad definida
* en la clase Contribuyente
oContr.cRegimenSS = "Autonomo"
Como todo Contribuyente es tambin una Persona, tiene todos los mtodos y
propiedades de la clase Persona.
La herencia nos va a facilitar enormemente el mantenimiento del cdigo. Por una
parte podemos heredar en vez de modificar la clase base y de esa forma preservar
la naturaleza de los objetos sin necesidad de modificar cientos de programas.
Por otra aparte, cualquier modificacin que realicemos en una clase, se ve reflejada
automticamente en todas las clases que hereden de ella. Por ejemplo, si aadimos
una nueva propiedad a la clase Persona o modificamos alguno de sus mtodos, esa
modificacin tambin se ve reflejada en el comportamiento de los objetos
Contribuyente, pues tambin son del tipo Persona.
Identificar Clases y Herencias. La programacin orientada a objeto exige de
nuevas tcnicas de anlisis orientada objeto. Cuando nos enfrentamos a un
programa realizado bajo estas tcnicas la mayores dificultades las tenemos en
identificar la clases correctamente y en definir las relaciones entre las distintas
clases.
No es fcil al principio, pero en poco tiempo la definicin de clases y las herencias
entre ellas ser un trabajo tan sencillo como ahora identificar cuando debemos
hacer una subrutina.
Sobreescribir mtodos o propiedades. En algunos casos, en la clase hija,
queremos modificar el comportamiento de algn mtodo o el contenido de alguna
propiedad de la clase padre. Este hecho se denomina sobreescribir. Con l somos
capaces de modificar los miembros de una clase padre sin afectar al cdigo de la
misma.
En el siguiente caso la clase Persona tiene un mtodo denominado Imprimir y la
claseContribuyente va a sobreescribir este mtodo con el suyo propio.
DEFINE CLASS persona AS CUSTOM
cNombre = ""
cApellidos = ""
dFechaNacimiento = {}
cEstadoCivil = "Soltero"

PROCEDURE Imprimir
? "Nombre : " ;
+ This.cNombre ;
+ " " ;
+ This.cApellidos
? "Fecha de nacimiento : " ;
+ DTOC( This.cFechaNacimiento )
? "Estado civil : " ;
+ This.cEstadoCivil
ENDPROC
ENDDEFINE

* Clase nueva
DEFINE CLASS Contribuyente AS Persona
cNIF = ""
nBaseImponible = 0
cRegimenSS = ""

PROCEDURE Imprimir
? "Nombre : " ;
+ This.cNombre ;
+ " " ;
+ This.cApellidos
? "Fecha de nacimiento : " ;
+ DTOC( This.dFechaNacimiento )
? "Estado civil : " ;
+ This.cEstadoCivil
? "NIF : " ;
+ This.cNIF
? "Base Imponible : " ;
+ STR( This.nBaseImponible )
? "Regimen de la S.S. : " ;
+ This.cRegimenSS
ENDPROC
ENDDEFINE
Cuando llamemos al mtodo imprimir, depender de la clase de objeto que
utilicemos se llamar a un mtodo o a otro.
oPrue1 = CREATEOBJECT( "Persona" )
oPrue1.cNombre = "Juan"
oPrue1.cApellidos = "Lpez Garrido"

oPrue2 = CREATEOBJECT( "Contribuyente" )
oPrue2.cNombre = "Pedro"
oPrue2.cApellidos = "Gomz Iriarte"

oPrue1.Imprimir()&& De persona
oPrue2.Imprimir()&& De contribuyente
Cuando escribamos un mtodo denominado Init o Destroy lo que estamos
haciendo es sobrescribir el mtodo por defecto para este evento. De igual forma
podemos sobre escribir cualquier otro mtodo o evento de una clase.
Recordemos lo que decamos antes sobre el Polimorfismo, este es otro ejemplo de
esta caracterstica, tenemos dos mtodos con el mismo nombre en clases
diferentes, pero en este caso, las clases se heredan una de otra, sobrescribiendo
este mtodo.

El Operador ::. Si es observador se habr percatado que en ejemplo anterior
estamos duplicando parte del cdigo del mtodo Imprimir de la clase Persona en
el mtodo imprimir la clase Contribuyente, esto no parece muy acertado para
ayudar al mantenimiento del cdigo.
En algunos casos queremos sobrescribir totalmente el mtodo de la clase padre,
pero en otros casos lo que deseamos en slo incluir nuevas prestaciones, pero
manteniendo el cdigo anterior. Para estos casos se ha creado el operador :: u
operador de resolucin de alcance. Con el podemos hacer referencia al mtodo de
una clase superior aun cuando este mtodo se hubiera sobrescrito.
Para hacer uso de este operador debemos indicar el nombre de la clase padre, el
operador ::, y el nombre del mtodo. Haciendo uso de este operador podramos
haber escrito la clase Contribuyente de la siguiente forma:
DEFINE CLASS Contribuyente AS Persona
cNIF = ""
nBaseImponible = 0
cRegimenSS = ""

PROCEDURE Imprimir

* Llamada al procedimiento
* original de la clase Persona
Persona::Imprimir() && OPERADOR ::

* Resto de impresin
? "Estado civil : " ;
+ This.cEstadoCivil
? "NIF : " ;
+ This.cNIF
? "Base Imponible : " ;
+ STR( This.nBaseImponible )
? "Regimen de la S.S. : " ;
+ This.cRegimenSS
ENDPROC
ENDDEFINE
Esta caracterstica nos asegura un buen mantenimiento de nuestras clases, pues
cualquier modificacin en el mtodo de la clase padre, se ve automticamente
reflejado en el mtodo de la clase hija, aunque este sobre escrito el mtodo.
Conclusiones
Han sido muchos conceptos seguidos y es posible que se sienta un poco aturdido
con tantas palabras. No se preocupe, como decamos al principio, la POO es un
conjunto de conceptos interrelacionados que difcilmente se entiende unos sin los
otros. Poco a poco ir comprendiendo su significado y concluir que no estn difcil
como algunos quieren hacer creer.
En los siguientes artculos haremos referencia a los conceptos aqu esbozados y
esperemos que se vaya encontrando ms fcil su compresin a medida que
avancemos.
En este artculo solo hemos creado clases partiendo de CUSTOM y siempre han sido
clases muy poco prcticas, pero prometemos realizar algunas clases que si merecen
la pena ser utilizadas.
Tambin describiremos las herramientas que VFP nos da para una hacer ms fcil
la POO, las clases que nos facilita y el modo de trabajar con ellas.
La POO est aqu y no deberamos ignorarla por ms tiempo. Posiblemente no es
necesario este tipo de programacin, pero es realmente muy recomendable, es
seguro que no soluciona todos los problemas, pero es mucho ms sencillo el
desarrollo, tendremos que esforzarnos un poco al principio, pero nuestro esfuerzo
se ver sobradamente recompensado. En definitiva, la Programacin Orientada a
Objeto es una mejor forma de programar.

Vous aimerez peut-être aussi