Aprendiendo OOPS 
 
Ultimamente habris observado cmo cada vez se habla ms  y  ms  del  OOPS 
(Object  Oriented Programming System = Sistema de Programacin Orientada al 
Objeto).  Ya  os coment en su da que esto iba a ser as. Y el caso es que 
va  a  ir  a mucho ms. El gran 'chaparrn' de OOPS se producir tan pronto 
como aparezca la nueva versin de Clipper (esperemos que no tarde mucho en 
salir!).
 
Por  el  momento,  las  reacciones  que  se  van  produciendo  son bastante 
curiosas. Hay quienes salen 'espantados' nada ms mencionarles la palabrita 
mgica  (OOPS)  y hay quienes, sin saber de que estan hablando, se declarn 
cmo feroces partidarios y defensores del OOPS.
 
La cuestin es que la mayora de los productos que estn a nuestro  alcance 
y  que  nos permiten usar estas tcnicas (Classy, SuperClass, oClip), estan 
escasamente documentados. Ante  esta  situacin  muchos  programadores  han 
optado  por esperar a que Clipper nos brinde totalmente esas posibilidades. 
Otros, por el contrario, empiezan a aadir excesivas dosis de 'imaginacin' 
al tema, e inventan lo que no han ledo ni estudiado por ninguna parte...
 
Aun  cuando  se  sabe  positivamente que la prxima versin de Clipper va a 
incorporar  plena  capacidad  OOPS,  me  daris  la  razn  en  que esto no 
significa que Clipper nos vaya a ensear a utilizar a 100% el OOPS. El OOPS 
requiere  estudio  y  mucha prctica. Tambin os quiero prevenir de algunas 
publicaciones  que han aparecido y que aparecern y que, ms que ensear lo 
que pueden, hacen que nos confundamos definitivamente. Acabo de revisar  un 
libro que se supone que es para  aprender  OOPS  y  en  todo  el  libro  no 
mencionan  para  nada  la  palabra  'Clase'...  y dice cosas como que de un 
Objeto se puede derivar otro Objeto...

 
 Dnde se puede aprender OOPS ? 

Cuando sent la curiosidad de aprender estas  tcnicas  observ  esta  gran 
confusin que os comento. Cada autor hablaba de lo que l crea que era  el 
OOPS.  Con  muy poco rigor. Con muy poca experimentacin... Es por esto que 
pens  que  el  C++  deba  ser una de las maneras ms precisas de aprender 
OOPS.  Pensad que el lenguaje C es uno de los lenguajes ms importantes que 
existen,  y  que  se  jugaba  mucho al evolucionar haca el C++. Aprender a 
programar en C++ os garantiza una slida base en OOPS.
 
S,  de  acuerdo,  esto no es ningn consejo fcil de seguir. Para aprender 
C++ es preciso que sepis bien C, y que conozcis a fondo las  limitaciones 
del  C. Slo as es posible entender las nuevas posibilidades que ofrece el 
C++. Y la nica forma de aprender todo esto es compraros un compilador de C 
y C++, y poneros a programar con  ellos  como  si  se  tratasen  del  nico 
lenguaje de programacin que existiese... y echarle muchas, muchas horas...
 
 
Pero...  Qu es un Objeto ? 
 
El concepto de Objeto es el punto de partida del OOPS. La nocin de  Objeto 
es algo intuitivo, ya que todos estamos 'rodeados' de Objetos. Lo que ya no 
es tan fcil es el intentar explicar y definir  que  es  un  Objeto.  Todos 
podis entender que una silla, un ordenador, una impresora y un  coche  son 
Objetos.  Sin  embargo,  entender que un 'Get' puede ser un Objeto ya no es 
tan fcil. Menos an, entender que un 'Error' tambin puede ser un Objeto.
 
Un  Objeto  es un conjunto de DATOS, y ese conjunto de DATOS se COMPORTA de 
determinadas  maneras, maneras que son iguales para los Objetos de la misma 
Clase.
 
Por  ejemplo,    qu datos tiene un coche ? Un coche tiene 4 ruedas y 1 de 
repuesto, puertas, un volante, unos asientos, un color, un tamao, un peso, 
etc., etc...
 
Ahora  os  pregunto  Qu datos tiene un Get de Clipper ? Cuando hacemos un 
Get  de  la  forma  @  nFila,  nColumna  GET  xVariable, ese Get tiene unas 
determinadas  coordenadas  en  pantalla  (  nFila,  nColumna  ).  Tiene  un 
determinado color, tiene la informacin que contiene xVariable, puede tener 
asociado una determinada funcin con la  que  validar  lo  que  escribamos, 
tiene un cursor parpadeando en unas determinadas coordenadas, etc...
 
 Vis la similitud con el mundo real ? Lo que de verdad conocemos  de  los 
Objetos  que nos rodean son sus datos caractersticos. Lo que tambin os he 
dicho es que esos datos se comportan de unas maneras caractersticas, y que 
esas maneras son las mismas para todos los Objetos de la misma Clase.
 
 Cmo se comporta un coche ? Sabemos que podemos arrancarlo y  que  cuando 
pisamos el acelerador se desplaza de un sitio a otro. Si giramos el volante 
las  ruedas  doblan  y  cambiamos  de direccin, si accionamos una manivela 
abresus ventanillas, si se queda sin gasolina se para, etc, etc...
 
  Cmo  se comporta un Get de Clipper ? Sabemos que si hacemos READ el Get 
se activa y podemos escribir en l. El cursor se comporta de  unas  maneras 
caractersticas.  Si  hay  un  grupo de Gets, el que est activo muestra el 
cursor y puede cambiar su color. Al  pulsar  [Intro]  pasa  el  control  al 
siguiente,  siempre  y cuando no haya una condicin de validacin que no se 
cumpla, etc...
 
 Vis nuevamente la similitud ? Si os paris un momento a pensar en lo que 
sabis hacer con Clipper veris que en vuestra mente mantenis una serie de 
Objetos... Si alguien os pide que hagis un programa rpidamente pensis en 
cmo vis a construir ese programa: Tendr un Menu, una pantalla de entrada 
de  datos,  manejar  una serie de DBFs y de ndices, generar una serie de 
listados, etc...  Estis pensando en Objetos ! 
 
Si  alguien  os  pregunta  Qu es un men ? contestis "tiene una serie de 
opciones  y  el  usuario  puede  elegir una de ellas"  Cmo se comporta un 
men? "Mediante el uso de determinadas teclas el  men  cambia  de  opcin, 
hasta que se pulsa [Intro] o [Esc]"...  Son Objetos !

  Dnde  est  entonces  el problema ? En que cuando os ponis a programar 
"descomponis" esos Objetos que  habis  pensado  en  variables  sueltas  y 
aisladas y en funciones que pueden hacer que os liis bastante... Ese es el 
problema. De la idea clara y precisa que tenais en vuestra mente, pasis a 
trocearla y a perder la simpleza que todo tena en vuestro diseo original.
 
El OOPS lo que te propone es pasar esa idea clara y simple a tu cdigo, sin 
alteraciones, sin modificaciones.  El problema tal cual ! 

  
y ...  Qu es una Clase ? 
 
Desde pequeos nos ensaan en la escuela la idea de  los  "Conjuntos".  Los 
conjuntos son elementos del mismo tipo.  Y qu significa "del mismo tipo"? 
Pues  elementos  que tienen los mismos datos y que se comportan de la misma 
manera.
 
Si yo digo "aqu tengo un conjunto de bolgrafos", quiere decir  que  todos 
esos Objetos son bolgrafos. Pueden ser distintos, de  distintas  formas  y 
distintos colores, pero sabemos que todos son bolgrafos.
 
Podemos tener una serie de Gets en pantalla y sabemos que todos  ellos  son 
Gets. Aunque tengan longitud distinta y contenidos distintos.
 
Una clase establece el tipo de datos que ha de tener un Objeto, y establece 
tambin  la  forma  de  comportarse de esos Objetos. De un modo ms tcnico 
podemos decir que la Clase es un  conjunto  de  reglas  de  creacin  y  de 
comportamiento de los Objetos.
 
As, la Clase Coche es distinta a la Clase Barco, o a la Clase Avin. 
As, la Clase Get es distinta a la Clase TBrowse, o a la Clase Error.
 
 
pero...  Cmo se disea una Clase en Clipper ? 
 
Vamos  a aplicar lo que acabamos de ver. El desafo que tenemos que superar 
es el de ser capaces de reconocer nuevamente esos Objetos que al  principio 
del diseo de nuestros programas tenamos tan  claramente  establecidos  en 
nuestra mente...
 
Acordaros  de  ese  momento  en que pensasteis "Bien, ah voy a dibujar una 
ventana".  Cuando  empezasteis  a codificar destrozasteis la idea tan clara 
que tenais. Creasteis una serie de variables sueltas, aisladas y una serie 
de  funciones sueltas y sin conexin, pero la idea era mucho ms simple que 
todo eso. Era tan slo  dibujar una ventana ! 
 
Lo primero que tenemos que hacer es crear la Clase Ventana. Hemos visto que 
una Clase nos indicar cmo crear Objetos de esa Clase e inidicar cmo han 
de comportarse esos Objetos...  Cmo se hace una Clase Ventana ? 

Primero, escribimos: 
 
   CLASS Ventana 
 
Segundo, pensamos qu datos tienen todas las ventanas: 
 
   VAR nArriba, nIzquierda, nAbajo, nDerecha 
 
Esos datos guardarn las coordenadas de la ventana en pantalla 
 
   VAR cColor, cMarco, cFondo, cTitulo 
 
Esos datos guardarn el color, el marco, el fondo de detrs y el ttulo que 
queramos ponerle a la ventana.
 
Tercero, hemos de declarar los mtodos, es decir la forma de comportarse de 
una ventana genrica. Lo primero es  declarar  el  mtodo  constructor,  es 
decir, indicarle a Clipper cmo se construye una ventana genrica: 
 
    METHOD New 
 
Pongamos ms mtodos, por ejemplo que se muestre y que se oculte: 
 
    METHOD Muestra 
    METHOD Oculta 
 
y al final indicamos ENDCLASS (Para estas  pruebas  podis  usar  oClip,  o 
Classy, o SuperClass o Dialog! :-) ). Ha de quedar as: 
 
CLASS Ventana 
 
  VAR nArriba, nIzquierda, nAbajo, nDerecha 
  VAR cColor, cMarco, cFondo, cTitulo 
 
  METHOD New 
  METHOD Muestra 
  METHOD Oculta 
 
ENDCLASS 
 
Bien,  ya  le hemos indicado a Clipper cmo va a ser la Clase Ventana. Pero 
Clipper  no sabe cmo se inicializa una Ventana, no sabe que ha de hacer el 
'constructor'. Vamos all: 
 
METHOD function New( nArriba, nIzquierda, nAbajo, nDerecha, cTitulo ) 
 
  ::nArriba    = nArriba 
  ::nIzquierda = nIzquierda 
  ::nAbajo     = nAbajo 
  ::nDerecha   = nDerecha 
  ::cColor     = "N/W" 
  ::cMarco     = "Ŀ" 
  ::cFondo     = "" 
  ::cTitulo    = cTitulo 
 
return Self 
 
 Qu es lo que hace exactamente un constructor ? Debis tener presente que 
Clipper  guarda los datos de los Objetos dentro de un array. Cuando Clipper 
inicializa un Objeto lo que hace es asignarle el valor NIL a  cada  uno  de 
los datos del Objeto.
 
Sin embargo, si definimos un Objeto, al que Clipper le  ha  asignado  todos 
sus datos nil, y queremos empezar a  utilizarlo, podemos  tener  problemas. 
Por  qu  ?  Porque  posiblemente  nosotros  necesitamos que los datos del 
Objeto mantengan algunos valores por defecto. Esto es lo que hemos de hacer 
en  el  constructor: asignar los valores por defecto necesarios para que el 
Objeto pueda funcionar correctamente.
 
  Que  significa  Self  ?. Self es una palabra reservada que usaremos para 
referirnos  al  propio Objeto. En C++, por ejemplo, se usa la palabra this, 
la utilidad es exactamente  la  misma.  Cuando  al  final  del  constructor 
escribimos   Self   queremos   indicar   que   una  vez  est  inicializado 
convenientemente el Objeto, devolvemos el mismo Objeto.
 
  Que  significa  el Operador :: ? En C++ el operador :: es un operador de 
'mbito'. En Clipper an no se ha implementado con toda su potencia. Por el 
momento :: quiere indicar lo  mismo  que  Self:,  es  decir  si  escribimos 
::nArriba = nArriba Quiere decir el  el  dato  nArriba  del  propio  Objeto 
(Self) lo hacemos igual al parmetro Self.
 
 
 Cmo nos comunicamos con los Objetos ? 
 
Una  vez tengamos definida nuestra Clase (en esta explicacin y por motivos 
de espacio no incluyo todo el desarrollo de construccin de la  Clase,  (si 
te interesa el tema, adquiere :-) la librera Dialog, all  podrs  revisar 
un  buen  montn  de cdigo fuente) el siguiente paso es crear un Objeto de 
esa Clase.
 
Si nuestra Clase se llama Ventana ( CLASS Ventana ), la forma de crear  una 
Ventana es: 
 
       local vtnTest := Ventana() 
 
Escribo 'vtn' como abreviacin de VenTaNa y Test  para  indicar  un  nombre 
cualquiera (esto es una de las reglas de la Notacin Hngara). Al llamar  a 
la funcin Ventana, Clipper construir un Objeto  Ventana  genrico.  Ahora 
bien, hemos visto que de poco nos servir el que cada dato del  Objeto  sea 
NIL.  Es  por  esto que lo primero que vamos a hacer es enviarle el MENSAJE 
New: 
 
       local vtnTest := Ventana():New() 
 
Como los constructors deben  devolver  el  propio  Objeto  (Self),  tenemos 
garantizado   que   nuestro  Objeto  vtnTest  recibir  un  Objeto  Ventana 
debidamente inicializado.
 
Esta es la primera situacin en que  nos  comunicamos  con  el  Objeto,  al 
aplicar el mtodo constructor. Os deca al principio de este  artculo  que 
un  Objeto  tiene  datos y se comporta de manera caracterstica a su Clase. 
Pero,  cmo  conseguimos  que  se  ejecute  ese  comportamiento  ?   Cmo 
conseguimos que el Objeto se ponga en marcha ? Envindole MENSAJES.
 
Al enviar un mensaje a un Objeto,  ste  ejecuta  los  mtodos  apropiados, 
segn los hayamos definido en la Clase. Clipper nos da el operador ':' para 
envos de mensajes. Si, por ejemplo, yo quiero que la ventana se muestre en 
pantalla entonces le envo al Objeto el mensaje 'muestra': 
 
           vtnTest:Muestra() 
 
El  Objeto, al  recibir  ese  mensaje  pondr  en  funcionamiento el mtodo 
adecuado.

 
Hay mucho ms...
 
Posiblemente te estars preguntando si todo esto no puedes hacerlo t ya en 
tus  programas, usando  arrays  y  funciones  y  dejando  de lado toda esta 
historia  'rara'  de  Objetos  y  Clases.  Esa es la primera 'tentacin' de 
abandono del OOPS... mi respuesta es tajante: no. El OOPS es algo  nuevo  y 
muy superior! Hay mucho ms de lo que te he contado aqu. Hay que  entender 
ms cosas, hay que ver ejemplos, hay que experimentar.
 
Lo verdaderamente importante y revolucionario del OOPS es la herencia.  Con 
la herencia el OOPS cobra todo su sentido y potencia. Y si sabemos  aplicar 
la  herencia (a travs de una jerarqua de Clases) es cuando nuestro cdigo 
sufrir una profunda transformacin. Y no slo eso: descubrirs que vuelves 
a  pensar  con  la  simpleza con la que analizabas los programas. El cdigo 
comienza a reflejar fielmente el anlisis que hicistis de la aplicacin.
 
Sin ninguna duda, el OOPS es la evolucin de la programacin  estructurada. 
Todos los fabricantes de Software ya estn ah, y nosotros... hemos  de  ir 
detrs. Una vez que lo pruebes te aseguro que no volvers atrs.