Apúntate...


Consultas, desarrollo de programas y petición de presupuestos:

Mostrando entradas con la etiqueta poo. Mostrar todas las entradas
Mostrando entradas con la etiqueta poo. Mostrar todas las entradas

miércoles, 26 de marzo de 2014

Clase

¿que es una clase?

En la programación orientada a objetos, una clase es una construcción que se utiliza como un modelo (o plantilla) para crear objetos de ese tipo. El modelo describe el estado y contiene el comportamiento que todos los objetos creados a partir de esa clase tendrán. Un objeto creado a partir de una determinada clase se denomina una instancia de esa clase.
Una clase por lo general representa un sustantivo, como una persona, lugar o cosa. Es el modelo de un concepto dentro de un programa de computadora. Fundamentalmente, delimita los posibles estados y define el comportamiento del concepto que representa. Encapsula el estado a través de espacios de almacenaje de datos llamados atributos, y encapsula el comportamiento a través de secciones de código reutilizables llamadas métodos.

Ejemplo:

La clase "perro", tiene propiedades:
- color
- raza
- peso
y tiene métodos:
- ladrar
- comer


La clase "perro" la podemos representar como este dibujo genérico (modelo o plantilla):

Un objeto de la clase "perro" (instancia de la clase "perro") identifica a un perro en concreto.
El perro "pluto"

El perro "lassie"






Referencia:
http://es.wikipedia.org/wiki/Clase_(inform%C3%A1tica)

sábado, 2 de noviembre de 2013

La Herencia entre clases: inherits

¿que es la herencia?
 La herencia facilita la creación de objetos a partir de otros ya existentes e implica que una subclase obtiene todo el comportamiento (métodos) y eventualmente los atributos (variables) de su superclase.
La clase de la que se hereda se suele denominar clase base, clase padre, superclase, clase ancestro.
La clase derivada de la herencia, se le puede añadir sus propios métodos o cambiar los definidos en la clase superclase, para modificar su comportamiento.

Es a destacar, el hecho de que cuando se usa como parámetro en una función una clase padre, dicha función admitirá también como objetos válidos, los objetos heredados de la clase padre.

Fig 1: Esquema del uso de herencia simple con clase padre: Persona,
y clases heredadas: administrativo, docente y personal limpieza

Ref: http://es.wikipedia.org/wiki/Herencia_(inform%C3%A1tica)

¿como se consigue la herencia en Gambas3?
Simplemente al iniciar la clase, se usa esta orden:


  • INHERITS ParentClass


Donde ParentClass es la clase de la que queremos heredar los métodos y propiedades.

En gambas3 solo existe la "herencia Simple", la herencia múltiple hay que simularla mediante composición de clases.


Ejemplo:
Hacer un programa que registe los Docentes, Administrativos y personal de limpieza. Con los métodos y atributos de la figura 1.
Haremos la siguiente estructura de clases:

Declararemos la clase Persona:
->
En la función registrar (número de linea 51), se dejan varios parámetros en forma de opcional (se pueden poner o no) y tipo variant (que admitirían cualquier tipo de datos), que nos servirán para usarlo en las clases heredadas.

Declaremos las clases que la heredan:
Administrativos
->
Docente:
->
A destacar la linea 43 donde se hace uso de Me.Sueldo() para calcularlo segun la funcion que esta definida en la clase (lineas 57 y sucesivas). Sin embargo en la linea 40, se hace uso de Super.Nombre para llamar a la clase padre.

PersonalLimpieza
->
Y la clase Main: (inicio del programa)
->
Aqui podemos destacar el uso de la funcion mostrar(), que recibe una clase persona (o cualquiera que herede de ella) y trabaja con los métodos que tenga sin ningún problema. Por ejemplo en este caso se le envia una clase PersonalLimpieza y nos muestra sus datos


Codigo completo: enlace a box.com

jueves, 3 de enero de 2013

Inputs vs Eventos: Reaccionar ante una acción

Hasta ahora, en nuestros programas de "consola", las acciones de los usuarios, las íbamos controlando mediante la orden "input", donde el usuario escribía algo (por ejemplo la opción de un menú) y el programa decidía que hacer a continuación (hacer listados, añadir registros pidiendo mas datos, salir del programa, etc...)

En la programación gráfica, vamos a tener una serie de objetos (botones, cuadros de textos, etc), los cuales son la forma en que el usuario se va a comunicar con la aplicación, y mediante eventos se recoge la acción realizada por el usuario.

Por ejemplo, un usuario hace click con el ratón sobre un botón llamado "Button1" se produce un "evento" llamado _Click(), y se ejecuta el código que tenga dicho botón asociado a ese evento:



Public Sub Button1_Click()

  Print "hola"

End





Al ejecutarse "Button1_Click()", lo que se produce es una impresión en la consola de la palabra "hola". (La consola también es accesible desde las aplicaciones gráficas)



Como veis, la forma  de programar un evento es como si fuera una subrutina, siendo el nombre de la subrutina formado por el nombre del objeto (Button1)  seguido de un guión bajo "_" y el nombre del evento "Click()"

Esta forma permite también, que dentro del mismo programa, mediante código, se puedan ejecutar estos eventos...

Public Sub Form_Open()

Button1_Click()

End



Normalmente cada objeto tiene varios eventos a los que responden, para ver los eventos que tienen, en la pantalla gráfica, se hace click con el botón derecho sobre ellos, se despliega el siguiente menu, y eligiendo la opción de "Eventos", podemos ver todos los eventos relacionados con ese objeto:


Hay eventos que son comunes a todos los objetos, y otros no.

A continuación pongo una lista de los eventos más usuales:


Evento
Significado
Click
El usuario hace una pulsación “click” sobre el objeto (pulsa y suelta el boton rapidamente)
DblClick
El usuario hace dos pulsaciones rápidas sobre el objeto
Enter
Se produce cuando entramos en el objeto con el puntero del raton
Leave
Se produce cuando sale del objeto con el puntero del raton
GotFocus
Se produce cuando el objeto consigue ser el foco del programa
LostFocus
Se produce cuando el objeto pierde el foco del programa
Drag/Drog
Eventos relacionados con “coger y soltar”
KeyPress
Se produce cuando estamos en el objeto (tenemos el foco en el) y se pulsa una tecla. Para sabe que tecla se ha pulsado se usa “key.code”, el cual nos da el numero ASCII de la tecla pulsada.
MouseDown
Si se pulsa el boton del raton
MouseUp
Si se suelta el boton del raton.
MouseMove
Si esta pulsado el boton del raton, y lo movemos dentro del objeto se produce este evento. Se pueden obtener las coordenadas del raton, con mouse.x y mouse.y

Os dejo aqui el código de ejemplo de uso de eventos con un botón: PruebasEventosBoton



Para saber más: Programación dirigida por Eventos

sábado, 15 de septiembre de 2012

Mas Sobre Constructores y Hacer una Copia de un Objeto

Mas Sobre Constructores

 En el post anterior hablamos sobre el método especial "_new", que nos ayuda a dar valores a los parámetros o realizar instrucciones justo cuando instanciamos un objeto.


Los métodos también admiten (al igual que las funciones y las subrutinas), parámetros opcionales (optional). Además tenemos funciones en gambas que permiten conocer que tipo de parámetro es el que se le esta pasando al instanciar la clase.

Con esta dos herramientas, podemos programar que un mismo método _new, pueda crear objetos usando diversos tipos y números de parámetros.

Por ejemplo:

Tenemos la clase ClassCirculo, con la cual se crean Circulos.
Podemos definir los circulos de diversas maneras:
  • Forma 1:  x, y, radio, nos dan la X e Y y radio (integer)
  • Forma 2:  x, y, radio,  nos dan la X e Y y radio (pero son Float)
  • Forma 3:  classe Coordenada, radio (circulo dado el centro por la clase coordenada y su radio)
  • Forma 4: clase coordenda1,coordenado2,coordenada3 (circulo que pase por 3 puntos)
¿como se programa?
Lo que tenemos que hacer es usar varias ordenes If... then,,, para que segun sea el tipo de parametro pasar crearlo.

Para saber el tipo de parámetro, usamos:
  • La orden TypeOf(parametro1), nos devuelve un número que se identifica con el tipo de variable  (ver http://www.gambasdoc.org/help/lang/typeof?v3 )
  • Si sabemos que es un objeto  Object.Type(parametro1), que nos dá el nombre de la clase.

¿Como se defineria la clase ClassCirculo?
-->
Public Sub _new(Optional parametro1 As Variant, Optional parametro2 As Variant, Optional parametro3 As Variant)

' Forma: x, y, radio : nos dan la X e Y y radio (integer)

If TypeOf(parametro1) = gb.Integer And TypeOf(parametro2) = gb.Integer And TypeOf(parametro3) = gb.integer Then
Print "Me pasan 3 numeros integer, en la forma X, Y, Radio"
'realizo copia de propiedades...
'...
hx = parametro1
hy = parametro2
hradio = parametro3
estado = "iniciado"
Return
Else
' Forma: x, y, radio : nos dan la X e Y y radio (pero son Float)
If TypeOf(parametro1) = gb.float And TypeOf(parametro2) = gb.float And TypeOf(parametro3) = gb.float Then
Print "Me pasan 3 numeros float, en la forma X, Y, Radio"
'crearia el circulo
'...
hx = parametro1
hy = parametro2
hradio = parametro3
Return
Else

' forma: classe Coordenada, radio (circulo dado el centro por la clase coordenada y su radio)
If Object.Type(parametro1) = "ClassCoordenada" And TypeOf(parametro2) = gb.float Then
Print "Me pasan una clase ClassCoordenada, y el Radio (float)"
'crearia el circulo con los datos pasado
'....
'
Return
Else
' Forma: clase coordenda1,coordenado2,coordenada3 (circulo que pase por 3 puntos)
If Object.Type(parametro1) = "ClassCoordenada" And Object.Type(parametro2) = "ClassCoordenada" And Object.Type(parametro3) = "ClassCoordenada" Then
Print "Me pasan 3 clases ClassCoordenada"
'se crearia el circulo teniendo en cuenta 3 coordenadas.
'....
'
Return
Endif
Endif
Endif
Endif

¿como usar la clase?
-->
Print "================================================================"
Print "= Constructores ="
Print "================================================================"

' Forma: x, y, radio : nos dan la X e Y y radio (integer)
Print "Constructor caso:"
c1 = New ClassCirculo(2, 3, 4)
' Forma: x, y, radio : nos dan la X e Y y radio ( Float)
Print "Constructor caso:"
c2 = New ClassCirculo(2.3, 24.2, 34.2)

' forma: classe Coordenada, radio (circulo dado el centro por la clase coordenada y su radio (float))
Print "Constructor caso:"
c3 = New ClassCirculo(coord1, 34.3)

' Forma: clase coordenda1,coordenado2,coordenada3 (circulo que pase por 3 puntos)
Print "Constructor caso:"
c4 = New ClassCirculo(coord1, coord2, coord3)

 Hacer una Copia de un Objeto:

Para copiar variables en Gambas, usamos el operador igual "=".
Por ejemplo
-->
dim Nombre as string

dim NombreCopia as string

Nombre=”Julio”
NombreCopia=nombre

print Nombre, NombreCopia

Sin embargo, con objetos no podemos hacer lo mismo, ya que  el operador igual ("=") lo que hace es copiar la referencia del objeto (no hace copia). Cualquier cambio que haríamos en el objecto copiado modificaria al objeto original.

-->
Print "Coordenadas Mal copiadas por referencia!!!: "

Print coord1.escribe()
Print coord2.escribe()

coord2.y = 234343455

Print "Coordenadas: "
Print coord1.escribe()
Print coord2.escribe()

Obtenemos en pantalla...
Coordenadas Mal copiadas por referencia!!!:
 X: 23 Y: 34
 X: 23 Y: 34
Coordenadas:
 X: 23 Y: 234343455
 X: 23 Y: 234343455
Como ves, al alterar la clase copiada (coord2), se modifica tambien la clase origen (coord1)

Para copiar objetos, tenemos que hacerlo mediante lineas de código, que se encarguen de copiar y asignar las propieades (sus valores) del objeto Origen a las otras propiedades del objeto_copia. Por ejemplo, con este método dentro de la clase ClassCoordenada
-->
Public Function copia(origen As ClassCoordenada) As ClassCoordenada
Me.x = origen.x
Me.y = origen.y
End


'Esta es la opcion más correcta vease comentarios...


Public Sub copia(origen As ClassCoordenada)

Me.x = origen.x
Me.y = origen.y

End


Para usarlo:
-->
coord1 = New ClassCoordenada
coord2 = New ClassCoordenada

coord1.x = 23
coord1.y = 34


coord2.copia(coord1)
Print "Coordenadas: Copia mediante metodo "
Print coord1.escribe()
Print coord2.escribe()
coord2.y = 3433445

Print "Coordenadas Cambio: "
Print coord1.escribe()
Print coord2.escribe()

Y es resultado...
Coordenadas:  Copia mediante metodo
 X: 23 Y: 34
 X: 23 Y: 34
Coordenadas Cambio:
 X: 23 Y: 34
 X: 23 Y: 3433445
Como veis, ahora si, se copia bien, ya que al modificar la clase copiada, la de origen no se modifica.

Para terminar, tambien podemos usar el método contructor para que crear una copia de un objeto:
-->
Public Sub _new(Optional parametro1 As Variant, Optional parametro2 As Variant, Optional parametro3 As Variant)

Dim clase As String
If TypeOf(parametro1) = gb.Object And If Object.Type(parametro1) = "ClassCirculo" Then

hy = parametro1.y
hx = parametro1.x
hradio = parametro1.radio
estado = parametro1.leerEstado()
Return
Endif
…..
…..

Y usarlo asi:
-->
Print "Proceso de copia de circulo.."
copia = New ClassCirculo(c1)



Para más información: http://www.gambas-es.org/viewtopic.php?f=1&t=100&highlight=objetos

Descarga del Código Fuente de ejmplo. tanto de Sobre Constructores y Copia de Objetos : Enlace


Nota: Actualizacion 3/8/2013 (new)
Tras estudiar un ejemplo del foro de gambas de Francia (http://www.gambasforge.org/code-62-copier-un-controle-ou-un-conteneur-et-ses-enfants.html), sobre como clonar controels, he realizado  algunos cambios para que nos sirva para objetos complejos (con propiedades que sean arrays, clases, variant, ...)

Os dejo aqui la función que lo hace:


Public Sub CopyObject(hObjeto As Object) As Object
Dim hNewMe As Object = Object.New(Object.Type(hObjeto)) 'se genera un objeto de la mismo tipo que nos pasan
Dim s As String 'variable utilizada para almacenar el valor de hclass.symbols
Dim hclass As Class = Object.Class(hObjeto) 'contiene el valor de la clase del objeto
Dim hChild As Object
Dim nuevoObjeto As Object
Dim caso As Integer 'tipo de dato de la propiedad del objeto
Dim contador, a As Integer 'para usarlo en bucle si son arrays
Dim arrayPosible As Object
'Inicio de la copia de las propiedades....
For Each s In hclass.Symbols
If s = "Chlidren" Then Continue
If Not hclass[s].ReadOnly Then
caso = TypeOf(Object.GetProperty(hObjeto, s))
Select Case caso
Case gb.Object
'la propiedad es un objeto, vuelvo a llamar a la funcion para que me extraiga los valores y no las referencias
nuevoObjeto = CopyObject(Object.GetProperty(hObjeto, s))
Object.SetProperty(hNewMe, s, nuevoObjeto)
Try contador = Object.GetProperty(hObjeto, s).count
If Error Then
'no es un array
Else
For a = 0 To contador - 1
nuevoObjeto.add(Object.GetProperty(hObjeto, s)[a])
Next
Endif
Default
'la propiedad no es un objeto, copio el valor
Object.SetProperty(hNewMe, s, Object.GetProperty(hObjeto, s))
End Select
Endif
Next
'devuelvo la copia del objeto
Return hNewMe
End

Y un ejemplo:
http://jsbsan.blogspot.com.es/2013/08/poo-en-gambas3-copiar-objetos.html

Nota 2:
Esta función copia tanto las propiedades como los métodos que tenga el objeto.
No copia variables publicas definidas dentro del objeto (ni por supuesto las privadas)









sábado, 1 de septiembre de 2012

Recorrer los controles que tenga un formulario

Algunas veces nos interesa recorrer los controles que tenga un formulario. Como los controles son enumerables, podemos usar un bucle For Each

Por ejemplo, nos interesa pasar a una función, los comboxes que haya el formulario que estemos:

DIM uncombo AS Object 'definimos un objeto temporal "uncombo"

FOR EACH uncombo IN ME.Controls 'recorremos todos los controles que hay en el formulario actual (Me)
'uncombo ira tomando los distintos objetos, que haya
IF uncombo IS Combobox THEN
' como el objeto uncombo es del tipo Combobox, lo pasamos a una funcion
funcion(uncombo)
ENDIF
NEXT

Otro ejemplo:
Esta vez, se trata de realizar algo según el control:
Si en un Combobox, ejecuta la funcion HacerAlgoConCombobox. 
Si es un Button, ejecuta la funcion HacerAlgoConButton.
Y si no es ninguno de lo anterior, simplente escribe el nombre interno del objeto y su tipo.

Public Sub Form_Open()

Dim objTemp As Object 'definimos un objeto temporal

For Each objTemp In Me.Controls 'recorremos todos los controles que hay en el formulario actual (Me)

Select object.Type(objTemp)
Case "ComboBox"
HacerAlgoConCombobox(objTemp)
Case "Button"
HacerAlgoConButton(objTemp)
Default
'si no es nada de lo anterior muestra el nombre del control interno y su tipo.
Print objtemp, object.Type(objtemp)

End Select
Next

End

Public Sub HacerAlgoConCombobox(obj As ComboBox)
Print "Es un combobox..."; obj
End
Public Sub HacerAlgoConButton(obj As Button)
Print "Es un Button..."; obj
End

Descarga del Código fuente: enlace
Descarga del ejecutable .gambas: enlace


Fuente:
Post del Foro Gambas-Es.Org
http://gambas-basico.blogspot.com.es/2012/06/bucles-anidados.html

A falta de donativos... un poco de publicidad