Objetos
User Objects
Además de los objetos predefinidos recientemente visto, cualquier lenguaje orientado a objetos debe permitir que el desarrollador puede crear sus propios objetos.
Esto puede hacerse de dos maneras ligeramente diferentes:
- Objetos autodefinidos
- Objetos anónimos
Objetos autodefinidos
Los objetos autodefinidos permiten hacer definiciones custom con estado y comportamiento particular. Otros nombres con los que pueden encontrarse en diferente bibliografía son Named Objects, “Well-Known Objects” (wko) o “singleton”.
Para definir un objeto utilizamos esta construcción:
A partir de aquí podemos acceder en cualquier parte del programa a la referencia “miObjeto”.
Objetos anonimos
Otra opción es utilizar objetos literales sin explícitamente darle un nombre. Esto permite usarlos en el momento sin utilizar una referencia o asignarlo a una variable de alcance más limitado que el global.
El objeto creado sirve a modo de ejemplo didáctico, ya que es un objeto vacío. En la consola sólo se verá
Metodos
Dentro de las llaves de un objeto se puede definir su comportamiento mediante la implementación de métodos. Por ejemplo representaremos un pájaro:
Los métodos se definen mediante la palabra method. Pueden recibir de 0 a n parámetros y opcionalmente devolver un valor. Los tipos de los parámetros no hay que definirlos. En caso que tenga, cada parámetro es una referencia que estará presente en el contexto del método a evaluar.
En el caso de que el método devuelva un valor es obligatorio escribir una sentencia return, a excepción de los simple return method explicados en la siguiente sección.
Simple Return Method
Hay un shortcut para definir métodos simples de una línea que solo devuelven valores.
El lector podrá notar que no es necesario escribir return, ni tampoco las llaves que encierren el cuerpo del método. Las llaves se reemplazan por el símbolo =, que indica que la evaluación de la parte derecha del método será el valor devuelto.
Atributos
Hasta el momento pepita no hace cosas muy interesantes, retorna siempre lo mismo o solo dependiendo de los parámetros que recibe en los mensajes. Así que le agregaremos “estado” al objeto, mediante atributos, también llamados variables de instancia, en los cuales va a guardar valores, recordar información y en definitiva hacer referencia a otros objetos. Algunos métodos harán que el estado del objeto cambie, asignándole nuevos valores a los atributos. A su vez, el mismo estado del objeto influirá en la respuesta de otros métodos.
El atributo energia inicialmente tiene un valor de 100, cada vez que se le envía el mensaje volar() o comer() a pepita el valor al que hace referencia energía va cambiando y cuando se le pregunta por estaFeliz(), la respuesta depende del valor de energía del momento.
Las referencias de la instancia se declaran en un objeto, justo antes del primer método. Como hemos visto, las referencias pueden ser var o const.
Todas las referencias de instancia son sólo visibles dentro del mismo objeto, se pueden acceder desde cualquiera de sus métodos.
Estas expresiones no son válidas.
Mensajes
Uno de los conceptos más importantes de la programación orientada a objetos son los mensajes. En Wollok, (casi) todo lo que uno hace es enviar mensajes a objetos.
Al enviar el mensaje a un objeto se ejecuta la definición del método.
Para enviar un mensaje la sintaxis es:
Estas variantes no son válidas:
Self
¿Qué pasa cuando estoy en un objeto y quiero enviarme un mensaje a mí mismo para aprovechar un método existente?
En ese caso utilizamos self que es una referencia que apunta al objeto donde estamos escribiendo el código.
Polimorfismo
El polimorfismo es la capacidad de un objeto de ser intercambiable con otro, sin que un tercero que los usa se vea afectado.
Wollok comparte algunas características con los lenguages dinámicamente tipados, ya que tiene un Pluggable Type System. Esto significa que si dos objetos entienden los mismos mensajes, entonces no necesitamos nada más para que un tercero los use en forma polimórfica.
Por ejemplo, cambiaremos la forma de comer de pepita. En vez de directamente decirle la cantidad de gramos que come, se le indica qué cosa comer, de manera que la cantidad de gramos va a depender de la comida que se le pase por parámetro.
El método comer() puede recibir en el parámetro comida cualquier objeto que entienda el mensaje energia() y devuelva un número (la cantidad de energía que provee).
Por ejemplo, se puede tener diferentes objetos que representen cosas que pepita pueda comer:
Aquí tanto alpiste como arroz son polimórficos respecto a pepita en el mensaje comer().
If
La expresión if permite evaluar una condición booleana y realizar diferentes acciones para el caso verdadero y falso respectivamente.
Por ejemplo:
En Wollok el “if” no es una sentencia (que controla el flujo) sino más bien una expresión. Esto implica que devuelve un valor, lo que permite cambiar el ejemplo a esta otra forma:
Propiedades
Una facilidad que ofrece Wollok es definir los atributos como propiedades, lo que asume automáticamente la existencia de métodos de acceso, sin tener que explicitarlos en el código (tarea que suele ser repetitiva para escribir y molesta para leer). Se declaran con la palabra property antes del nombre de la referencia. En el caso de las variables incluye getters y setters, en el caso de las constantes, solo los getters
El siguiente ejemplo…
… sin perder funcionalidad, puede reescribirse así:
En ambos casos es equivalente consultar: