Hasta ahora hemos aprendido a jugar con algunos objetos. Jugamos con objetos números, strings, arrays, lápices y caritas. Les hemos enviados mensajes y hemos observado la respuesta. También inspeccionamos objetos por dentro, utilizamos nombres para referirnos a ellos y también hemos podido indagar algunos métodos a través de los cuales los objetos responden a los mensajes.
Observen que sin querer hemos clasificado los objetos. Cuando decimos que hemos jugado con lápices, nos estamos refiriendo a muchos objetos (lapices) con los que hemos jugado, que en nuestra clasificación se diferencian de otros objetos arrays o strings o caritas con los que también hemos jugado.
En nuestra vida diaria (al igual que como ocurre en nuestro ambiente Smallatalk) nuestro cerebro clasifica las cosas que percibimos. Cuando caminamos por la calle y vemos un gato de carne y hueso, al identificarlo como gato lo estamos clasificando bajo un concepto abstracto "Gato" que existe en nuestro cerebro. En este caso podemos decir que, por un lado, hay en la calle un gato "real" de carne y hueso y, por otro lado, hay un Gato "concepto" en nuestro cerebro que sirve para clasificar como gato a eso de carne y hueso que percibimos en la calle.
Si seguimos caminando y en la otra cuadra encontramos otro gato real de carne y hueso, emerge nuevamente el concepto Gato en nuestro cerebro, que nos sirve para clasificarlo.
Es importante notar que el concepto (en este caso Gato) y la cosa que percibimos en la calle (el gato de carne y hueso) son dos cosas distintas. El concepto sirve para clasificar/caracterizar a la "cosa" que percibimos. Además, este tipo de concepto se diferencia de cualquier otra clasificación, porque define las caracteríticas esenciales de la cosa que percibimos: las características que no cambian durante el lapso de vida. Es más, este concepto tiene la posibilidad de perdurar por sobre la "cosa" percibida. Aunque el gato concreto que vemos en la calle se muera y desaparezca, el concepto Gato podrá seguir perdurando como tal en nuestro cerebro y podrá ser reutilizado, por ejemplo, para clasificar otro gato en el futuro. En el caso de Dinosaurio, es evidente que ya no existe ningún dinosaurio de carne y hueso, sin embargo "Dinosaurio" como concepto perdura.
En Smalltalk también existe una relación entre las cosas y su concepto. A las cosas se las llama instancia y a los objetos que definen y caracterizan a las instancias se los llama clases. Volviendo a nuestros lápices, cuando nosotros jugábamos con ellos, estábamos jugando con instancias de la clase Pen. Todos esos lápices con los que jugábamos tenían en común a (eran de) la clase Pen.
Para concer a que Clase pertenece un objeto cualquiera, basta con enviarle el mensaje class. Veámoslo: abramos un workspace y hagamos "print it" de las siguientes expresiones.
5 class
'Hola como te va' class
En Smalltalk las clases caracterizan y definen el comportamiento de las instancias. Además, las clases sirven para crear instancias nuevas. Probémoslo en un workspace evaluando con "do it" lo siguiente
pepe := Pen new.
juan := Pen new.
Hemos creado dos instancias nuevas de la clase Pen. Estas dos instancias son dos lápices a los que les pusimos el nomber pepe y juan. Para crear una instancia lapiz, hemos enviado el mensaje new al objeto Pen (que es una clase).
Ahora coloquen el Workspace abajo a la derecha, redúzcanle un poco el tamaño y juguemos un poco más, haciendo "do it" de lo siguiente
pepe goto: 100 @ 300.
pepe go: 100
juan go:100.
juan turn:
90.
juan go: 100.
juan turn: 45.
juan go: 100.
Como hemos dicho antes, en la clase Pen se define el comportamiento que van a tener las instancias juan y pepe (en nuestro caso). Para explorar la clase Pen y conocer los métodos con los cuales juan y pepe respondieron a los mensajes go: y turn: , hagamos lo siguiente. Escribamos en el workspace la palabra Pen, seleccionémosla, luego con la palabra seleccionada apretemos el botón derecho del mouse, elijamos la opción "more..." y luego la opción "browse it". Aparecerá el System Browser donde se podrá observar la clase Pen. En el panel de arriba a la derecha se observará la lista de métodos, con los cuales las instancias de Pen responden a los mensajes. Por ejemplo, seleccionemos haciendo click con el mouse el método go: y en el panel de abajo aparecerá la definción de este método. También, podemos buscar en el panel arriba a la derecha el método turn: seleccionarlo y observar en el panel de abajo la definición de este método.
Por ahora no nos preocupemos demasiado en entender la definición de los métodos ni las otras cosas que aparecen en el System Browser. Lo importante es la idea de que:
Smalltalk tiene muchísimas clases. Podemos acceder a las mismas mediante el System Browser, para observarlas, modificarlas o definir nuevas clases. Para modelar y desarrollar cosas en Squeak, nuestro trabajo consistirá justamente en esto. A partir de las clases, crearemos (instanciaremos) objetos que interactuarán con nosotros y entre ellos mediante el envío de mensajes.
Volvamos a los gatos. El concepto Gato que tenemos en la cabeza es un
subconcepto del concepto Felino, que a su vez es un subconcepto de Mamífero, que
a su vez es un subconcepto de Animal. Y si seguimos subiendo en la jerarquia,
podemos decir que Animal es un subconcepto de Cosa
Cosa - Animal -
Mamífero - Felino - Gato
En este orden jerárquico, toda característica de un concepto superior también es propiedad de un subconcepto. Si decimos que una característica de Mamífero es: "mama leche de la teta", también Felino va a poseer esta característica y también Gato. Cuando identificamos en un subconcepto una característica definida en un concepto superior, decimos que el subconcepto hereda esta caracterítica.
En la organización de los conceptos, la jerarquía a menudo presenta una organización de árbol. Por ejemplo, si incluimos a la jerarquía el concepto de Tigre, podemos decir que es un subconcepto de Felino. De esta manera, encontramos una "ramificación" en la jerarquía a nivel de Felino.
En Smalltalk las clases están ordenadas en una jerarquía de árbol como la recientemente descripta, pero obviamente con una cantidad mucho mayor de clases. Todas las clases se agrupan en un único árbol jerárquico cuyo nivel superior inicial es la clase Object y a partir de esta clase comienza la ramificación de subclases. Para ver esto inspeccionaremos la clase Number. Escribamos en un workspace la palabra Number, seleccionemosla, apretemos el botón derecho del mouse, elijamos opción "more..." y luego la opción "browse it". Aparecerá un System Browser mostrando la clase Number. Leyendo el panel inferior podrán darse cuenta que Number es una subclase de Magnitud. Apretando el botón "hierarchy" se abrirá otro browser (agrande el tamaño del mismo) en cuyo panel superior izquierdo podrán ver toda la jerarquía de clases relacionada con la clase Number.
Para cumplir con el propósito de definir las características y el comportamiento de las instancias, la clase posee dos tipos de definiciones principales: variables de instancias y métodos.
Volvamos a jugar con los lápices. Evaluemos los siguientes renglones.
juan := Pen new.
pedro := Pen new.
juan goto: 100 @ 200.
pedro
goto: 200 @ 200.
pedro turn: 45.
Cuando le mandamos el mensaje
juan go: 100.
pedro go: 100.
juan (una instancia de la clase Pen) responde moviéndose en la pantalla hacia arriba y dejando un trazo. Lo propio hace pedro pero moviéndose desde otro lugar y en otra dirección. Podemos intuir que internamente cada uno de estos objetos "conoce" su dirección y su posición. De esta manera puede responder al mensaje go:.
Efectivamente, los objetos de la clase Pen conocen la posición, la dirección y algunas otras cosas más. Para ello cada objeto tiene nombres internos (variables de instancia) que utilizan para hacer referencia a otros objetos. En nuestro ejemplo tanto pedro como juan poseen internamente las variables de instancia location y direction. Estas hacen referencia a un objeto de la clase Point y a un objeto de la clase Number respectivamente. Obviamente el objeto de la clase Point al que hace referencia la variable de instancia position de pedro, no es el mismo objeto al que hace referencia la variable de instancia position de juan.
Veamos esto: En el mismo workspace seleccionemos la palabra juan, botón derecho del mouse y elijamos "inspect it". Se abrirá un inspector que nos permitirá indagar a juan (una instancia de la clase Pen) por dentro. Desplazándose por el panel superior izquierdo, podrán observar las variables de instancia location y direction. Seleccionandolas una a, podremos observar, en el panel superior derecho, los objetos a los que hacen referencia. En el caso de juan, direction hace referencia al objeto número 270 (se refiere a los grados) y location hace referencia al objeto punto 100@100 (se refiere a la posición actual de juan en la pantalla).
Los nombres de las variables de instancia que usan las instancias se definen en la clase. En nuestro caso, los nombres de las variables de instancia location y direction (entre otras) que usan tanto pedro como juan se definen en la clase Pen. Para ver esto, escribamos en un workspace la palabra Pen, seleccionemosla, apretemos el botón derecho del mouse, elijamos opción "more..." y luego la opción "browse it". Aparecerá un System Browser mostrando la clase Pen. Leyendo el panel inferior podremos darnos cuenta que se define los nombres location y direction (además de penDown), como nombres de variables de instancias.
Tanto pedro como juan han sabido responder a nuestros mensajes go: , goto: y turn:, la forma en la que la que estos objetos (instancias de Pen) responden a estos mensajes esta definida en la clase Pen mediante métodos. En la sección Clase e Instancia hemos indagado en la definición de algunos de los métodos de Pen.
En este documento hemos aprendido
- qué es una Clase y qué es una
Instancia,
- la relación entre ambas,
- la manera jerárquica en la que se organizan las clases
- las definiciones que se realizan en una Clase: nombres de las variables de
instancia y métodos,
Ahora podemos avanzar en la creación de nuestra primer clase ... siga este link