En 1994, Booch, Rumbaugh y Jacobson al unificar las notaciones de sus métodos, dan origen al UML: Unified Modeling Language
que es un lenguaje para visualizar, especificar, construir y documentar los artefactos (modelos) de un sistema que involucra una gran cantidad de software, desde una perspectiva OO.
|
||
de casos |
conceptual |
|
de interacción |
de Clases |
Como lenguaje sus características son:
- Orientación a Objetos
- Tipado dinámico
- Interacción entre objetos mediante envío de mensajes
- Herencia simple y con raíz común
- Reflexión computacional completa
- Recolección de basura
- Compilación en tiempo de ejecución o Interpretado.
- Múltiples Implementaciones
Un sistema Smalltalk posee:
- Una Máquina virtual (Virtual machine)
- Un archivo llamado "Imagen", que contiene a todos los objetos del sistema
- Un lenguaje de programación (también conocido como Smalltalk)
- Una biblioteca de "objetos reusables"
Características comunes de los objetos Smalltalk:
- Tienen una memoria propia.
- Poseen capacidad para comunicarse con otros objetos.
- Poseen capacidad de heredar características de objetos ancestros.
- Tienen capacidad de procesamiento.
- Los objetos se comunican entre sí mediante el envío de mensajes y cada objeto puede proveer muchas operaciones, cuyas definiciones son llamadas métodos.
- Un método especifica la reacción del objeto cuando recibe un mensaje dirigido a ese método, cuya resolución de un mensaje a un método es dinámica.
- Protocolo o interfaz de mensajes del objeto, es la colección de métodos del objeto.
- Los mensajes pueden ser parametrizados, estos parámetros serán objetos, y el resultado o respuesta del mismo también será un objeto.
- Las características comunes de objetos se registran en la noción de clase, así, los objetos agrupados bajo una clase son llamados instancias de ella.
- Las instancias se crean durante la ejecución del programa con algún propósito y son barridos automáticamente el recolector de basura,
cuando ya no son necesitados.
- Exceptuando algunos objetos especiales como los muy simples, llamados literales (números, cadenas, etc), cada objeto tiene su propio estado local y
representa una instancia diferente de su clase.
El entorno Smalltalk:
- Las mas conocidad implementaciones de Smalltalk son VisualWorks, Squeak, VisualSmalltalk, VisualAge, Dolphin, Pharo Smalltalk, Smalltalk X.
- Es un entorno de interacción diferente al entorno de desarrollo de otras tecnologías como Microsoft Visual Studio.Net o Eclipse.
- Es gráfico y funciona como sistema en tiempo de ejecución que integra varias herramientas de programación (Smalltalk),
utilidades multimedia, interfaces para ejecutar código no nativo a Smalltalk y servicios del sistema operativo.
- La metodología de trabajo y concepción de la programación, permiten considerar a Smalltalk más que un simple lenguaje de programación.
- No requiere para desarrollar software del ciclo típico de las tecnologías tradicionales: Arrancar un editor de texto, compilar y ejecutar y terminar la aplicación.
- Manipula el entorno mismo, comúnmente mediante el Navegador del Sistema.
La sintaxis de Smalltalk:
- No posee una notación explícita para describir un programa entero. Sí se utiliza una sintaxis explícita para definir ciertos elementos de un programa, tales como métodos, pero la manera en que tales elementos están estructurados dentro de un programa entero generalmente es definida por las múltiples implementaciones. El estándar mismo no promueve otra dirección, por lo que define una sintaxis abstracta de programas Smalltalk, que define todos los elementos que constituyen un programa Smalltalk y la manera en que esos elementos están lógicamente compuestos por otros elementos, sin embargo, cada implementación es libre de definir y utilizar las muchas sintaxis posibles que están conformes a la sintaxis abstracta estándar. Un ejemplo de una sintaxis concreta es el Formato de Intercambio Smalltalk (o SIF, de Smalltalk Interchange Format) definida en el mismo estándar.
- La sintaxis de Smalltalk-80 tiende a ser minimalista. Esto significa que existen un grupo pequeño de palabras reservadas y declaraciones en comparación con la mayoría de los lenguajes populares. Smalltalk posee un grupo de 5 palabras reservadas: self, super, nil, true y false.
Recolección de basura:
En Smalltalk no es necesario desalocar objetos explícitamente, por lo tanto no proporciona mecanismos para ello. Las implementaciones utilizan técnicas de recolección de basura para detectar y reclamar espacio en memoria asociado con objetos que ya no se utilizarán más en el sistema. En Smalltalk la recolección de basura es integrada configurable. La forma de ejecución del recolector de basura es en background, es decir, como un proceso de baja prioridad no interactivo, aunque en algunas implementaciones es posible ejecutarlo a demanda, siendo posible definir configuraciones de memoria especiales para cada sistema mediante políticas (por ejemplo en VisualWorks). La frecuencia y características de la recolección depende de la técnica utilizada por la implementación. Adicionalmente algunas implementaciones de Smalltalk proporcionan soporte para mecanismos de finalización como el uso de Ephemerons.
Reflexión computacional:
Smalltalk-80 provee reflexión computacional estructural y comportacional, ya que es un sistema implementado en sí mismo. La reflexión estructural se manifiesta en que las clases y métodos que define el sistema son en sí mismos objetos también y forman parte del sistema mismo. La mayoría de las implementaciones de Smalltalk tienden a exponer el compilador Smalltalk al entorno de programación, permitiendo que dentro del sistema se compile código fuente (textual), transformándose en objetos métodos, que son comúnmente instancias de la clase CompiledMethod. El sistema generalmente incorpora estos métodos en las clases, almacenándolos en el diccionario de métodos de la clase a la cual se quiera agregar el comportamiento que realiza el método. Esto, así como la incorporación de nuevas clases al sistema, es realizado dentro del sistema mismo; aunque la mayor parte de las implementaciones poseen herramientas visuales que ocultan la complejidad de interactuar con la clase que usualmente se encarga de tales tareas, el ClassBuilder.
La reflexión computacional de Smalltalk-80 se manifiesta en la posibilidad de observar el estado computacional del sistema. En los lenguajes derivados del Smalltalk-80 original, durante el envío de mensajes entre objetos, cada objeto receptor de un mensaje consulta su clase para tener acceso a los métodos que define. En caso de encontrarse el método en la clase, se dice que se "activa" el método. Esta activación de un método actualmente en ejecución, es accesible mediante una palabra clave llamada thisContext. Enviando mensajes a thisContext se puede consultar cuestiones tales como "¿quién me envió este mensaje?". Estas facilidades hacen posible implementar co-rutinas, continuaciones o back-tracking al estilo Prolog sin necesidad de modificar la máquina virtual. Uno de los usos más interesantes de esta facilidad, se da en el framework de web Seaside de Avi Bryant.
En Smalltalk todo es un objeto, y a un objeto se le envían mensajes. Ejemplo: 1 + 1
Significa que al objeto "1" le enviamos el mensaje "+" con el colaborador externo, otro objeto, "1". Este ejemplo entonces resulta en el objeto "2".
'¡Hola, mundo!' : En el típico Hola mundo, el objeto es Transcript, que recibe el mensaje show con el colaborador externo '¡Hola, Mundo!'.
Para crear una instancia de un objeto, se manda un mensaje new a una clase: ClaseDelObjeto new
Para obtener las vocales de una cadena de texto: 'Esto es un texto' select: [:aCharacter | aCharacter isVowel].
Haciendo doble click en el WorkSpace o Area de Trabajo, la pantalla siguiente:
Ahora ya puedes probar editando los siguientes ejemplos y luego correrlos.Para entender la precedencia, escribe 3+4*5 35 luego presiona CTRL + D y obtendrás un resultado. Despues digita 3+(4*5) 23 y vuelve a presionar CTRL + D
El orden de precedencia es de izquierda a derecha, siendo el mensaje que esta mas a la izquierda el primero en ser evaluado. y sobre la procedencia indicada por el orden de izquierda a derecha se ubica la precedencia relativa de los tres tipos de mensajes:
Se puede alterar la precedencia de izquierda a derecha por la inserción de paréntesis. La expresión entre paréntesis tiene la más alta precedencia.
MENSAJES EN Smalltalk:
Para ejecutar:
Veamos como agregar las clases nuevas de objeto a su imagen de Smalltalk y cómo programar su comportamiento agregando los métodos a ellos. Cuando haga esto, estará extendiendo las capacidades del sistema básico. Por esta razón, ahora debe guardar su imagen en una base regular (para evitar perder estos cambios) y al salir del ambiente de Dolphin.
Esto es lo que "programar" Smalltalk, está produciendo una imagen nueva con las clases y el comportamiento apropiados para hacer lo que usted quiere. Un "programa" de Smalltalk es una imagen con una red de objetos que interactúan.
El juego repleto se ha proporcionado en un paquete llamados Animales. En esta etapa, usted quizás quiera cargar esto en su imagen que utiliza el Package Browser (Examinador de Paquete) usted apenas puede ver lo que se piensa hacer. Debe encontrar el paquete en la guía Animals.pac (Muestras/Animal) del Juego abajo la ubicación donde Dolphin se instala. El doble clic sobre Animales.pac para instalarlo en su imagen.
Una vez que el paquete está en su imagen, entonces va a una área de trabajo y evalúa:
Animal playGame.(PlayGame animal)
Se le pedirá pensar en un animal y entonces responder a preguntas acerca del mismo. Inicialmente, el juego sólo sabe un animal (un perro) así que el primer redondo esté aburriendo bastante. Si el juego no sabe el animal que usted piensa en entonces pedirá que usted entre su nombre para que lo pueda aprender para el próximo tiempo. Se le pedirá también pensar en una pregunta que se distingue el animal nuevo de uno que ya en la base de datos. Cercióresele sigue las instrucciones aquí y entra una pregunta que queda el formato solicitado.
Cuándo usted se cansa de ensanchar la base Animal del conocimiento del juego entonces está segura desinstalar el paquete de su imagen para que usted pueda seguir el tutorial en este capítulo. Usted puede hacer este utilizar el Examinador de Paquete, la orden de menú de Paquete/Desinstala.
Cómo trabaja
Antes utilizamos el sistema del desarrollo de Dolphin para diseñar y construir este juego quizás sea útil mirar cómo trabaja. Consideremos exactamente lo que hace este juego. Construye una base del conocimiento de los animales que sabe acerca de y, en la orden para ser capaz de adivinar sensatamente, esto debe contener también las preguntas que permiten distinguirse entre un animal y otro. En esta versión del juego cada pregunta tiene una respuesta un sí o no. Esto nos quizás dirija a pensar que un "árbol" de objetos algo como el siguiente puede representar la base del conocimiento:
Esto es un árbol invertido con su raíz (raíces) a la cabeza del esquema. Los nodos marrones de la Pregunta representan las ramas y las hojas están en los nodos Animales en verde. Escoja uno de los animales en el esquema (Perro, la Serpiente, el Aguila o el Caballo) como su adivinación y siga el árbol de la decisión por de la raíz del árbol que empieza en la flecha marrón.
Así parece que podemos construir nuestra base animal del conocimiento de dos clases de objeto; Animales y Preguntas. Tendremos que tener también el objeto de raíz de árbol (siempre una Pregunta) en algún lugar nosotros podemos obtener el acceso para comenzar el juego. Usted verá cómo hacer este más tarde.
El Derecho de la Herencia de la clase, nos permitió que ahora tratemos de agregar la clase Animal a nuestra imagen. Antes de hacer esto, nosotros necesitamos saber un poco acerca de herencia de clase. Abra Class Hierarchy Browser (Examinador de la Jerarquía de la Clase) y escoja Object (Objeto) en el panel de la jerarquía de clase de la izquierda por encima. Si Objeto es la única clase que es visible en este panel entonces haga doble clic para ensanchar el despliegue hasta que aparezca como abajo.
Cuando pueda ver, el browser (examinador) este despliega parte de las muchas clases que ya existen en la imagen. Estas clases existen en un hierarchy (jerarquía) donde cada clase (aparte de Objeto) es un hijo de algún padre. Esta jerarquía es importante dado que rige cómo alguna clase particular que puede "heredar" algunas funciones de su de padre. Por ejemplo, con Objeto escogido, el browser (examinador) estará demostrando todos los métodos definidos para esta clase en el panel del método en el derecho primero. Ahora haga clic en Boolean y usted verá una lista de sus métodos. Cuando usted puede ver, el número de los métodos que aparecen para estar disponible para Boolean es mucho más pequeño que para el Objeto. Sin embargo, esta no es la lista definitiva. Puesto que Boolean es una "subclase" de Objeto hereda todos los métodos, que significa esto, que los casos Boolean pueden responder a todos estos mensajes también.
Nota: Realmente, esto es más bien un ejemplo falso desde que los casos de Boolean nunca pueden existir. Es lo que se llama una clase abstracta. Si usted doble clic en Boolean para desplegarlo y mostrar sus subclases usted verá que tiene dos; Verdadero y Falso. Los casos de estas clases existen y ellos pueden responder a cualquiera de los mensajes definidos para el Objeto y Boolean así como esos definido para sí mismos.
Cuando usted pueda ver sin duda, esta herencia del comportamiento puede ser un gran salvador de tiempo. Escogiendo un lugar apropiado en la jerarquía para definir una clase nueva que usted puede salvarse para tener que reordenar, y para tener que duplicar, tener que codificar que ya se ha escrito y ha sido probado previamente.
Bueno, ahora para un par de definiciones. Hemos visto que una clase puede tener varias clases de hijo abajo. Estos son conocidos como sus subclases. Por lo tanto sigue que el padre de una clase particular debe ser igualmente conocido como su super clase. Cada clase aparte de Objeto tendrá uno, y sólo uno, la super clase pero puede tener muchas subclases. El objeto es extraordinario en no teniendo una super clase porque es la raíz de la jerarquía.
Nota: una vez más yo he introducido una simplificación leve aquí. Puede haber realmente otras clases como Objeto que existe en la raíz de la jerarquía y por lo tanto no tiene super clases. Esto es bastante un tema tan avanzado que nosotros no lo moraremos aquí.
Las Relaciones de es-un y Contiene
Un apoyan así, al Animal. ¿En la jerarquía de la clase dónde debemos escoger crear esta clase? La primera cosa para considerar es qué tipo de información hace cada caso del asidero Animal. Mirando el conocimiento esquema despreciable encima se puede ver que cada animal debe saber por lo menos su nombre; es decir qué tipo de animal es. Esto estará en la forma de una String de texto de Smalltalk tal como: "Perro", "Gato", 'Caballo' etc. Así, una ubicación posible en la jerarquía de la clase que nosotros quizás consideremos sería de hacer Animal una subclase de String. Para mirar esta decisión con más detalle, encuentra la clase de String en el Class Hierarchy Browser
(Examinador de la Jerarquía de la Clase) (reString que usted puede hacer este utilizar la orden de menú de Class/Find [Clase/Hallazgo]) y echar una mirada a los métodos que se definen para todas Strings.
Si hacemos nuestra clase Animal e insertamos una subclase entonces heredaremos todos los métodos. Esto puede, o no puede, ser lo que nosotros queremos. ¿Piensa acerca de lo que tiene sentido para un Animal entender los mensajes tales como #> = y #asNumber etc.?
Lo qué nosotros debemos estar preguntando realmente si un Animal "es un String" o si, de hecho, "debe contener un" String. Esto es una de las decisiones fundamentales que los diseñadores de software hacen en un problema del diseño cuando ellos realizan un "análisis orientado a objetos". A menudo es un problema bastante complejo que vale dibujando un esquema del modelo de objeto y esto ilustrará las relaciones entre los objetos en el sistema. Las relaciones a menudo se describen como relaciones de Es-Un y Contiene-Un.
Es mi sugerencia, por lo tanto, que un Animal debe contener un String y no ser una subclase de uno. Así, nosotros aun no tenemos todavía definido exactamente donde Animal debe ser subclase global en la jerarquía(hierarchy). En estas situaciones es mejor empezar fuera con su clase siendo esta una subclase directa de Objeto (deberá representar un objeto a fin de cuentas). Esto es un punto de partida predefinido muy bueno. La gran cosa acerca de Smalltalk es eso, si usted posterior debe descubrir que hay una super clase más conveniente en algún lugar en la imagen, entonces es realmente fácil de redactar y mueve su clase a esta ubicación nueva en la jerarquía.
Ahora cree la clase Animal como una subclase de Objeto. Para hacer esto, seleccione el Objeto de super clase en el Class Hierarchy Browser (Examinador de la Jerarquía de la Clase, que se encuentra en el menu principal del compilador) y escoger Class/New (Clase/Nuevo). Usted será incitado a entrar un nombre para la clase que usted quiere crear; en este caso Animal.
Entonces usted verá que el Browser (examinador), ha creado su clase y le mostrará también una definición de Smalltalk, en el panel de la definición de la Clase mas abajo.
Nota:
En el fondo del área del Class Hierarchy Browser
(Examinador de la Jerarquía de la Clase) le puede mostrar
uno de tres paneles dependiendo de cuál etiqueta escoge.
Usted puede escoger de la Method source (fuente del Método),
Class definition (la definición de Clase) y Class
comment (el comentario de la clase).
En ese momento el panel de la definición de Clase se habrá escogido para mostrarle automáticamente la definición de a clase que acaba de crear. En el capítulo previo el contenido de este panel contiene una expresión de Smalltalk que se podría evaluar en cualquier área de trabajo para crear la clase. Mire de cerca y usted verá el mensaje
#subclass:instanceVariableNames:classVariableNames:poolDictionaries:
se manda a Object (Objeto) para hacer esto. Es conveniente que nosotros guardemos en el examinador lo tipeado, componer y evaluar esta expresión para nosotros.
Agregando el caso las variables
Ahora vuelvan a considerar los datos que nuestra clase Animal debe tener en cada caso. Mencionamos antes que necesitamos ser capaz de tener el nombre del animal como un String y por lo tanto necesitamos una variable instancia para hacer esto. De esta manera agregamos una variable instancia llamada el nombre. Utilizar el ratón, para colocar el cursor para la agregar texto en la cadena de caracteres que sigue inmediatamente
instanceVariableNames: y escribe a máquina la variable el nombre.
Object subclass: #Animal instanceVariableNames: 'el nombre' classVariableNames: '' poolDictionaries: ''
A fin de consignar este cambio en la imagen simplemente tipee CTRL +S o escoger Accept (Acepta) del menú del Workspace (Area de trabajo).
Felicitaciones, usted acaba de agregar su primera clase a su imagen del Dolphin. Usted puede cambiar la definición de la clase en cualquier momento simplemente modificándolo en el panel de Class definition (definición de Clase) y aceptando el cambio. Ahora quizás sea un tiempo conveniente de guardar su imagen.
Agregando los métodos
Nuestra próxima tarea será de utilizar al Class Hierarchy Browser (Examinador de la Jerarquía de Clase) para agregar algunas definiciones del método a la clase Animal.
Los métodos de acceso que agregan
Una de las cosas acerca de la programación orientado-objeto, y Smalltalk en particular, es que no es posible entrar a los datos almacenados en un objeto por medios de métodos escritos en la clase. Por ejemplo, nosotros queremos ser capaces de poner y recuperar el valor en el caso del nombre ranura variable de un Animal, para hacer esto, necesitará escribir un par de métodos. Estos son conocidos como métodos de acceso. Queremos agregar los métodos para #name and #name: .
Escoja la clase Animal en el Class Hierarchy Browser y escoja la opción Method/New
(Método/Nuevo). Esto establece al examinador y se prepara para recibir una definición nueva del método en el panel de Method source. Ingrese el método siguiente:
name
"Answer the name of the receiver"
^name
denomine "Contesta el nombre del receptor"
^el nombre
Escoja Workspace/Accept o presione Ctrl+S para aceptar esta definición nueva del método en la imagen. Usted verá eso, después que el examinador compila el método, es entonces mostrara de nuevo en el panel de source el texto en color. Los colores diferentes identifican las partes diferentes del idioma y pronto encontrará que esto hace más fáciles de leer los métodos.
El método que acabamos de agregar incluyó el símbolo ^ para indicar que un valor debe ser devuelto del método. La intención de este método de acceso, en particular deberá retornar el valor obtenido en la variable instancia name. Ahora agreguemos otro método de poner el valor de esta variable instancia. Escoja una vez más Method/New, entre y acepte el siguiente código:
name: aStringName
"Private - Initialize the name of the receiver to aStringName"
name := aStringName
el nombre: aStringName
"Privado - Inicializa el nombre del receptor al aStringName"
elnombre: = aStringName
Este método recibe un parámetro que he dado un nombre de aStringName para identificarlo. Advierta cómo que el nombre escogido para este parámetro puede indicar al lector del código que tipo de objeto es aceptable aquí, por ejemplo un String. Esto puramente se hace para la legibilidad, así que en ningún momento el sistema insiste que realmente sólo un String sea admisible. Puede ser una práctica útil la de entrar en el hábito de denominar los parámetros de esta manera para que alguien en el futuro, hojeando por los métodos de su programa tenga una mejor idea cómo utilizarlos.
El único propósito de este método deberá asignar el contenido del parámetro pasado a la variable del caso del nombre. Advierta que he escogido marcar el método como Private
(Privado) dentro de (method comment) comentario del método. Se discutió en el capítulo previo que Smalltalk no impone tal intimidad del método pero, una vez más, esto es útil documentación para cualquier programador que piensa en utilizar nuestra clase Animal. Qué indica esto, bajo circunstancias normales, uno no esperaría llamar este método directamente.
Nota: Usted puede estar preguntándose que este método no pretende ser llamado directamente. Veremos el razonamiento para este más tarde.
Clasificar los métodos
Nosotros mencionamos antes que es útil colocar los métodos en categorías para ayudar a identificarlos, y es mejor hacer esto cuando usted entra cada método. Hay varias maneras en las que el Class Hierarchy Browser lo puede ayudar a clasificar los métodos pero el más sencillo deberá pedir probablemente sugerir una categoría para usted. Escoja el método en cuestión, diga #elnombre, y escoja la categoría de Method/Suggest (Método/Sugiere). Usted será incitado con un diálogo de las sugerencias de la categoría que el examinador piensa que son convenientes para este método particular.
Esas categorías listaron con un + el símbolo adyacente a ellos pueden ser ensanchados. Sí, es cierto, las categorías pueden existir en una jerarquía también. Todo usted debe hacer el doble clic a la categoría que usted piensa que es apropiada para su método y se agregará automáticamente. En este caso, desde que tratamos con un método de acceso parecería apropiado entrarlo en la categoría de acceso.
Nota: Usted puede mentar también el diálogo de la sugerencia de la categoría haciendo clic sobre el método en cuestión con el botón derecho del ratón. Esto hace desplegar automáticamente un contexto del menú para el método y usted pueden escoger dentro de esto Suggest category(Sugiere la categoría) de dentro de esto.
Es siempre posible, y verdaderamente bastante probable, que la caja de sugerencia de categoría puede no contener una categoría que usted considera conveniente para su método. Si esto sucede, entonces haga clic en Cancel para descartar la caja y utilizar el Method/Category comando para traer el siguiente el diálogo alternativo que muestra una lista de todas las categorías en la imagen siguiente:
Nota: una vez más este diálogo puede ser traído también del menú del contexto para el método. Simplemente derecho-clic sobre el método y escoge la orden de la Category (Categoría).
De este diálogo usted puede asignar su método a cualquiera de las categorías existentes en el sistema y, si usted todavía no piensa que cualquiera de éstos es apropiado, usted puede crear una categoría nueva haciendo clic el botón New (Nuevo).
El tiempo para una Prueba
Lo bueno que tiene Smalltalk es que es realmente fácil de probar las cosas rápidamente. Por qué no creamos una instancia de Animal y vemos lo que podemos hacer consigo hasta ahora. En un workspace evalúa:
myAnimal := Animal new. "Display the following" myAnimal name. "Now give it a name" myAnimal name: 'Dog'. "And display the name again" myAnimal name.
MyAnimal: = Animal nuevo.
"Demuestra el siguiente" el nombre de myAnimal.
"Ahora le da un nombre" el nombre de myAnimal: "Perro".
"Y demuestra el nombre otra vez" el nombre de myAnimal.
Estas pruebas sencillas muestran cómo podemos crear un caso nuevo de un Animal, asignar un nombre a y entonces preguntar el nombre otra vez.
Bueno, mira atrás a esa prueba que acabamos de hacer. Inmediatamente después que nosotros habíamos creado la instancia nos preguntamos su nombre y volvimos (quizás) sorprendidos por el resultado; nil. Esto no es un valor especial que Smalltalk utiliza para indicar que una variable todavía no fue inicializada. Nil es realmente un objeto en su propio derecho (sí usted lo pregunta su clase contestará que es un caso de UndefinedObject). ¡En Smalltalk todo es un objeto!
Nil se puede utilizar para más probando apenas si algo es uninitialized (no inicializado). Usted también le encontrará útil en sus propios programas cuando quiere representar el concepto de algo está en un estado indefinido.
Instancias, creación de métodos
Por defecto, todas clases responden a un #new message (mensaje nuevo) y responden a una instancia de la clase. Utilizamos este hecho en nuestra prueba previa. Nosotros no escribimos el #new method (método nuevo) ya que todas clases heredan esto mediante su cadena de super clase.
Nota: Usted quizás espere encontrar este método en la clase Object. Sin embargo, no está allí, sino está en la Clase de la clase. ¿Por qué no utilizar al examinador para echar una mirada?
Sin embargo, utilizando #new (#nuevo) crear una instancia de Animal no es realmente ideal puesto que, como hemos visto, acabamos arriba con un animal que tiene un nombre nil. Sería mejor si aseguráramos como cada instancia es creada e inicializada apropiadamente con un nombre válido de String. Podemos hacer esto agregando un método de la creación de la instancia que toma como su parámetro el nombre del animal para ser creado. Tal método no es aplicable a un caso de Animal sino a la misma clase. Por esta razón se llama un método de la clase (contrariamente a las instancias de los métodos que hemos creado hasta ahora).
Para crear un método de la clase que usted debe primero seleccionar la etiqueta de la class hierarchy browser.
El examinador entonces cambiará a mostrar los métodos de la clase, de la clase actual antes que sus instancias de métodos. Ahora agregue el método siguiente al lado de la clase:
name: aStringName
"Answer an instance of the receiver with aStringName"
^self new name: aStringName
el nombre: aStringName "Contesta un caso del receptor con aStringName"
^el nombre auto nuevo: aStringName
Cuando usted pueda ver, esto crea una instancia nueva de Animal y entonces lo manda un #name: message (#elnombre: mensaje) para inicializar su nombre. Para indicar que esto es verdaderamente un método de creación de instancia, usted lo debe agregar a la categoría de la creación de instancia. Esta vez haciendo clic derecho de prueba encima del método y escoger la Category (Categoría) del menú móvil del contexto que aparece.
Nota: Ahora quizás llegue a ser aparente por qué nosotros marcamos el #name: method
(#elnombre: método) en la instancia de Animal como ser privado. La intención es que este método hace que sólo sea llamado del método de la clase del mismo nombre. Nosotros esperamos que una instancia Animal, una vez que se haya creado, no tendrá jamás su nombre cambiado tan nosotros indicamos esto sugiriendo el método es privado y por lo tanto no se debe llamar explícitamente.
Representar un objeto como texto
Hay muchas situaciones donde quizás queramos mostrar uno de nuestros objetos como un String de texto. Por la convención, Smalltalk proporciona varios métodos definidos en el Object para este propósito.
#displayString y #displayOn:
Se asume generalmente que estos mensajes se pueden utilizar para mostrar cualquier objeto como un usuario final esperaría verlos. El primer, #displayString, contestará una representación de String del objeto. El segundo toma un Stream como su único parámetro y produce la representación textual del objeto a esta corriente. Las corrientes son el sujeto de un capítulo posterior así nosotros no entraremos aquí con demasiado detalle acerca de ellos. La cosa para notar, sin embargo, es eso #displayString es aplicado generalmente en términos de #displayOn:. Esto significa que si necesitamos cambiar la manera que un objeto se representa como texto de usuario final, normalmente sólo necesitamos aplicar un #displayOn: el método. Ante todo, veamos cómo que un Animal responde a #displayString por omisión. Trate de ejecutar el ejemplo siguiente en una área de trabajo.
tiger := Animal name: 'Tiger'. "Display this" tiger displayString.
El tigre: = el nombre Animal: "Tigre".
"Demuestra esto"
tigre displayString.
Ahora, demostrando este apenas como un "un Animal" es seguramente un poco desilustrado. Haga caso omiso la implementación predefinida de #displayOn: (encontró en el Objeto y que proporciona el gruñe el trabajo para #displayString) informar por lo menos el nombre del animal implicado. Agregue el método siguiente al Animal.
IMPORTANTE: puesto que esto deberá ser un método del lado de la, instancia debe asegurarse hacer clic en la etiqueta de Instance, en el browser primero.
displayOn: aStream
"Answer the name of the receiver prepended by 'a' or 'an' as appropriate"
| aOrAn |
aOrAn := name first isVowel ifTrue: ['an '] ifFalse: ['a '].
aStream nextPutAll: aOrAn; nextPutAll: self name.
displayOn: aStream "Contesta el nombre del prepended de receptor por 'un' o 'un' apropia como"
| AOrAn | aOrAn: = denomina primero ifTrue de isVowel: [' un '] ifFalse: [' un ']. NextPutAll de aStream: aOrAn; nextPutAll: auto nombre.
Utilice el Sugiere la facilidad (Suggest category)de la categoría para agregar este método a la categoría que muestra.
Ahora probar #displayString otra vez y usted debe ver una representación más fácil de manejar del tigre:
"Display this"
tiger displayString.
"Demuestra esto"
tigre displayString.
La escritura un método como esto en una clase derivada, que tiene el mismo nombre como un método en una super clase, es conocida como hacer caso omiso el método original. Esto es otro aspecto importante que forma parte de la programación de orirntada-objeto.
#printString y #printOn:
Estos mensajes se utilizan en una manera semejante al #displayString y #displayOn:
los métodos excepto de aquellos que son pensados crear una representación textual de un objeto como un revelador (un antes que un usuario final). La implementación predefinido de estos métodos en el Object, meramente dirá el revelador lo que la clase del objeto es (por ejemplo: un Animal). Ahora hagamos caso omiso #printOn: mostrar también el nombre de animal junto con su clase.
printOn: aStream
"Answer the name of the receiver as a developer would wish to see it." super printOn: aStream.
aStream nextPut: $(.
self displayOn: aStream. aStream nextPut: $).
PrintOn: aStream "Contesta que el nombre del receptor como un revelador desearía verlo."
Super printOn: aStream. AStream nextPut: $ (. Auto displayOn: aStream. AStream nextPut: $).
Otra vez use Suggest category para clasificar el método, esta vez agregando a la categoría que imprime.
Para probar esto en el workspace, muestra el resultado de evaluar lo siguiente.
"Print this" tiger printString.
"Imprime esto"
printString de tigre.
Si todo ha ido según lo planeado esto debe imprimir "un Animal (un Tigre)". Siempre que usted agrega una clase nueva a su imagen debe considerar hacer caso omiso a uno o más del #displayOn: y #printOn: los métodos. Quizás quiera hacer esto incluso si no necesita mostrar su objeto como texto en su diseño inicial; es muy probable que esto podría llegar a ser un requisito en alguna vez en el futuro.
Self y Super
En el último método que agregamos logramos resbalar en un par de conceptos nuevos y muy importantes; Self y Super.
Si, en un método, nosotros queremos mandar otro mensaje al recibir el objeto entonces utilizamos el Self palabra reservada para representar el objeto. Eche una mirada al #printOn: el método otra vez para ver cómo es que trabaja. Queremos utilizar la habilidad de #displayOn: a la impresión del nombre de animal como una parte de la representación general. Hacemos esto mandando el #displayOn: message to Self.
Quizás un concepto más difícil de explicar es el de Super. Utilizamos esto cuando queremos mandar un mensaje al receptor pero nosotros no queremos ninguna declaración local (en la clase de receptor) del método correspondiente a ser ejecutado. Por lo tanto, cuando usted manda un mensaje a Super, el sistema empezará su búsqueda para el método de ejecutar, no en la clase del receptor, pero en su super clase. Esto es muy utilizado comúnmente al hacer caso omiso un método. A menudo usted querrá heredar la funcionalidad existente del método y querrá aumentarlo con su propio código adicional. Esto es exactamente lo que sucede en el #printOn: el método que acabamos de escribir.
¿La pregunta: Qué habría sucedido en este método si habíamos mandado por inadvertidamente #printOn: Self antes que Super?
Es una apuesta segura que aparecerá Self y Super extensamente en el código que usted escribe de ahora en adelante.
Crear la clase de la Pregunta
Nosotros mencionamos anteriormente que el juego Animal requeriría probablemente dos clases. Hasta ahora hemos agregado una clase que se llamó Animal y tenemos puesto en su lugar la funcionalidad básica para esto. Ahora creemos la segunda de las dos clases; la Pregunta.
¿Así que qué sabemos nosotros acerca de cómo debe comportarse una Pregunta? Bien, mira atrás al esquema en el principio de este capítulo que ilustra los datos estructura para un juego Animal típico. De la misma manera que cada objeto Animal tiene un nombre, nosotros requeriremos que cada Pregunta necesitará también tener en un String de texto que es la pregunta para ser preguntada (valga la redundancia). Además de esto, cada objeto de la Pregunta debe ser también capaz de indicar cuál rama del árbol debe seguir dado un sí o ninguna respuesta a la pregunta. Así parece sensato asumir que nosotros quizás necesitemos tres variables del caso, el texto, sí y no. Pensamiento acerca de lo, nosotros quizás decidamos también que la super clase más sensata para la Pregunta otra vez deberá ser Object. Soportando todo esto en la mente usted debe seguir los pasos siguientes para agregar esta clase nueva a su imagen.
Agregue la clase la Pregunta como una subclase de Object
Escoge Class Hierarchy Browser. Ahora utilice la Class/New de menú para crear la subclase de la Pregunta de Objeto. Agregue las variables nuevas del caso y vuelva a compilar la definición como esta indicado abajo.
Object subclass: #Question instanceVariableNames: 'text yes no' classVariableNames: '' poolDictionaries: ''
Object subclass: # Pregunta
InstanceVariableNames: 'texto sí no'
classVariableNames: ''
poolDictionaries: ''
Agrega los métodos de accesos
Ante todo agrega los métodos siguientes para ser capaz de obtener los valores de las tres variables de instancias.
yes "Answer the branch in the knowledge tree to take as the result of a 'yes' answer to the receiver's question."
^yes
no "Answer the branch in the knowledge tree to take as the result of a 'no' answer to the receiver's question."
^no
text "Answer the receiver's question as a text String"
^text
Sí "Contesta la rama en el árbol del conocimiento para tomar como el resultado de un 'Y respuesta a la pregunta del
receptor."
^Sí no "Contesta la rama en el árbol del conocimiento para tomar como el resultado de un 'no' la respuesta a la pregunta
del receptor."
^no texto "Contesta la pregunta de receptor como una String de texto"
^texto
Ciertamente será útil ser capaz de conseguir separadamente el acceso a los valores de estas variables. Sin embargo, una vez que el caso de la Pregunta se hayamos creado nosotros nunca debemos necesitar poner los valores de estas variables otra vez. Por lo tanto, tiene sentido que debemos ser capaces de utilizar un método privado para poner todas estas variables inmediatamente durante creación de la instancia. Utilizaremos el método siguiente para hacer esto:
text: aString yes: yesPath no: noPath
"Private - Set the text of the receiver to aString and the yes and no branches to
yesPath and noPath respectively. This is a bit tricky. At the end of this operation
we want the receiver to have completely swapped its identity with the original noPath. This is a bit of a kludge (since there are better ways to insert the receiver
in the knowledge tree at the right point) but it is the simplest solutionfor this
example program."
text := aString.
yes := yesPath.
no := self.
self become: noPath
El texto: aString sí: yesPath no: noPath "Privado - Puso el texto del receptor al aString y el sí y ningunas ramas al yesPath y
el noPath respectivamente. Esto es un poco complicado. A fines de esta operación nosotros queremos que el receptor para haber
cambiado completamente su identidad con el noPath original. Esto es un poco de un kludge (desde que hay mejores maneras de meter el receptor en el árbol del conocimiento en el punto correcto) pero son la solución más sencilla para este programa del ejemplo."
El texto: = aString. Sí: = yesPath. No: = el ser.
el ser llega a ser: noPath
Bien, para ser honesto, el uso del #become: message (#transformarse_en: mensaje) está más allá del alcance verdadero de este capítulo y su uso en este programa del ejemplo es sólo debido al hecho que quise de acortar el programa para hacerlo más fácil de entender. Sin embargo, para los que se interesan, la Nota debajo de explica por qué está aquí.
Nota: se Imagina un árbol existente del conocimiento para el juego (sugiero que usted se refiere a atrás al esquema original) y hemos llegado a la situación donde la computadora no sabe el animal en cuestión. Asumamos por esta descripción que la computadora cree que usted piensa probablemente acerca de un "águila" pero, de hecho, usted piensa acerca de un "gorrión".
Nosotros debemos crear un objeto Animal nuevo que representa el "gorrión" y también crear una Pregunta nueva que sea capaz de distinguir los dos animales. Cuándo nosotros hemos completado ligando estos dos objetos nuevos en nuestro conocimiento se basan la Pregunta original que llevó al nodo de "águila" ahora tendrá que señalar al nodo nuevo de la Pregunta que se distingue.
Para hacer de esto manera fácil deberá preguntar los dos objetos (el "águila" y la pregunta nueva) cambiar las identidades. Esto es lo que become: does (#llega a ser: hace).
Asegúrese de agregar estos métodos a la categoría accessing.
Agregar un método de la creación de la instancia.
Ahora nosotros necesitamos un método de la clase para utilizar al
crear una instancia de la Pregunta.
IMPORTANTE: asegúrese de poner al Class Hierarchy Browser en el modo de la Clase antes agregar este método de otro modo anulará lo que usted acaba de crear en el lado de la instancia.
text: aString yes: yesPath no: noPath
"Answer an instance of the receiver (a Question) having aString as it's text and
leading to the nodes at yesPath and noPath as the result of those answers to its question."
^self new text: aString yes: yesPath no: noPath
El texto: aString sí: yesPath no: noPath "Contesta un caso del receptor (una Pregunta) teniendo aString como es texto y
llevando a los nodos en yesPath y noPath como el resultado de esas respuestas a su pregunta."
^texto auto nuevo: aString sí: yesPath no: noPath
Este método debe entrar en la categoría de la instance creation (creación de una instancia).
Imprimir y mostrar una Pregunta.
Los métodos siguientes tienen en cuenta una Pregunta para ser representada como texto, del punto de vista de un usuario final y el creador respectivamente. Usted puede utilizar la característica de la category suggestion (sugerencia de la categoría) del browser (examinador) para colocar estos métodos en sus categorías correctas.
IMPORTANTE: Coloca atrás el examinador en el modo de la Instancia antes de agregar estos métodos.
displayOn: aStream
"Answer the name of the receiver as a user should see it. For this we append a question mark."
aStream nextPutAll: self text; nextPutAll: ' ?'.
printOn: aStream
"Answer the name of the receiver as a developer would wish to see it." super printOn: aStream.
aStream nextPut: $(.
self displayOn: aStream.
aStream nextPut: $).
DisplayOn: aStream "Contesta que el nombre del receptor como un usuario lo debe ver. Para este añadimos un
signo de interrogación."
NextPutAll de aStream: auto texto; nextPutAll: '?' PrintOn: aStream "Contesta que el nombre del receptor como
un revelador desearía verlo."
Super printOn: aStream. AStream nextPut: $ (. Auto displayOn: aStream. AStream nextPut: $).
Crear una variable de la clase para tener la base del conocimiento.
Alguna se ha mencionado que necesitaríamos tener la raíz de la base del conocimiento en una variable, si solamente así el juego sabrá donde obtener el asidero de ello cuando empieza. Ahora es el tiempo de crear e inicializar esta variable. Podemos, por supuesto, escoger utilizar una variable global para este propósito. Sin embargo, es usual fruncir el entrecejo sobre variables globales ya que ellas pueden chocar con variables semejantes denominadas en otra aplicación. Hay afortunadamente una alternativa excelente; utilizar una variable de la clase.
Hemos visto cómo que variables de caso se pueden utilizar para tener los datos que se asocian con un caso particular. Bien es también posible crear otro tipo de variable que se asocia con un objeto particular de la clase. Es muy fácil de agregar la clase ranuras variables a su clase utilizando al Class Hierarchy Browser. Escojamos para agregar una variable de la clase llamada KnowledgeBase a la clase Animal. El Animal ante todo selecto en el Browser y entonces escoge la etiqueta de la definición de la Clase para demostrar la definición existente. Modifique este como mostrado debajo de y acepte el cambio que utiliza CTRL + S.
Nota: es convencional para los nombres de variables de clase para empezar con una letra en mayúscula.
Esta variable nueva se puede utilizar como cualquier otro pero sólo dentro del alcance de la clase Animal. Esto significa que lo puede utilizar en cualquier método (o instancia o la clase) eso se define para el Animal o sus subclases. Sin embargo, no es capaz de mencionar exitosamente la variable KnowledgeBase de cualquier otra clase o workspace. Esto significa que usted no sería capaz de mencionarlo de dentro de la clase de la Pregunta, por ejemplo. Lo bueno que tiene este nivel adicional de la intimidad, que comparado con globales verdaderas es que ninguna otra clase o programa pueden modificar esta variable por inapropiadamente.
Nota: A Veces quizás quiera permitir a los métodos fuera del alcance normal que sean capaz de conseguir acceso a una variable de la clase. Esto es bastante posible, y es simplemente un asunto de definir algunos métodos de acceso, lo mismo que usted hace para variables de instancia. La única diferencia, por supuesto, es que los métodos de acceso que usted define para una variable de clase se deben definir como métodos de clase antes que las Instancias. De todos modos, en nuestro juego Animal sólo necesitamos mencionar el KnowledgeBase de dentro de la clase Animal y no tendremos necesidad para cualquier método de acceso.
E la próxima tarea deberá inicializar el KnowledgeBase para que tenga un objeto conveniente de raíz para el juego para empezar. Si agregamos esta inicialización como parte de un método de la clase entonces lo podemos volver a emplear cuando queremos limpiar el juego y comenzar de nuevo (se olvida que todo el juego ha aprendido). Agregue lo siguiente, class method al Animal y lo coloca en la categoría initializing (que inicializa).
initialize
"Initialize the Animal game knowledge base.
To start with we only know about Dogs"
KnowledgeBase := self name: 'Dog'
Inicialice "Inicializa la base Animal del conocimiento del juego. Para empezar con nosotros sólo sabe acerca de Perros"
KnowledgeBase: = auto nombre: 'Perro'
Cuando el método sugiere, empezaremos lejos con el juego sólo sabiendo acerca de perros.
Ahora, en un workspace, evalúa lo siguiente para realizar realmente la inicialización.
Animal initialize.
El animal inicializa.
Nota: La inclusión de un #initialize (#inicializa) el método de la clase tiene un significado adicional especial para cuando usted escoge guardar fuera su trabajo se puede importar en otra persona la imagen de Dolphin. Cuando una clase se carga en una imagen nueva comprueba el sistema para ver si #initialize (#inicializa) el método de la clase existe y, si hace, esto se ejecuta automáticamente. Por consiguiente, esta es una gran manera de asegurar esas variables de la clase (y semejante) sean establecidos apropiadamente.
Instalar el juego.
Ahora nosotros tenemos la mayor parte de los elementos en el lugar para nuestro juego Animal y acabamos de quedar para agregar unos pocos métodos que instalar todo junto. Ante todo, desde nosotros les estaremos agregando los métodos a la Pregunta y clases Animales, yo querría introducir un poco de la nomenclatura que ayudará a evitar cualquier confusión en cuanto a exactamente donde los métodos pertenecen. Eche una mirada a lo Siguiente:
Animal>>thisMethod
Indicates that thisMethod belongs on the instance side of the Animal class
Animal class>>thisMethod
Indicates that thisMethod belongs on the class side of the Animal class
Question>>thisMethod
Indicates that thisMethod belongs on the instance side of the Question class
Question>>thisMethod
Indicates that thisMethod belongs on the instance side of the Question class
El animal>> thisMethod Indica ese thisMethod pertenece en el lado del caso de la clase Animal la clase Animal>>
thisMethod Indica ese thisMethod pertenece en el lado de la clase de la Pregunta Animal de la clase>> thisMethod
Indica ese thisMethod pertenece en el lado del caso de la Pregunta de la clase de la Pregunta>> thisMethod Indica
ese thisMethod pertenece en el lado del caso de la clase de la Pregunta
Esto>> el símbolo se utiliza comúnmente para documentar que un método pertenece a una clase particular usted encontrará que nosotros lo utilizamos muy a menudo de ahora en adelante en esta guía.
Hacer las preguntas
Cuando un juego está en el progreso mucha de la acción será de hacer con la computadora que usted pregunte. Cuando el juego traza por el árbol del conocimiento, en algún tiempo particular estará mirando o un nodo de la Pregunta o, si sabe que animal es, un nodo Animal. ¿Cómo es que usted trazó el camino dentro del posible esquema original del juego? Si ese es el caso, usted verá cómo que la computadora debe colocar una pregunta al jugador humano en cada etapa. Por ejemplo:
¿ "Tiene alas?" - para un objeto de la Pregunta o
¿ "Piensa usted en un Aguila?" - Para un objeto Animal.
Ahora la cosa interesante aquí está que podemos escribir el juego para que no necesite estar enterado de qué tipo de nodo se trata en cualquier momento. Puede andar alrededor mandando apenas una #ask (#pregunta) (dice) el mensaje a cada nodo que encuentra y, proporcionando aplicamos un conveniente #ask (#pregunta) el método en cada una de las clases de Animal y Pregunta todo debe funcionar correctamente. Como quitar un objeto, especificando el comportamiento es una parte fundamental de la programación orientado-objeto. Llamamos este Polimorfismo o el comportamiento Polimórfico. La cosa clave es que las clases diferentes de objeto pueden responder al mismo método en maneras diferentes. Esto es gran instrumento porque significa que la necesidad de emisor no se preocupa por qué tipo de objeto es el receptor, que responde apropiadamente al mensaje para ser enviado.
Así que agreguemos nuestro polimórfico (es una gran palabra eso) #ask que los métodos Pregunten y el Animal. Colóquelos en la categoría de operations (operaciones).
Question>>ask
"Ask the receiver's question and continue the game appropriately
depending on the
answer that is received"
(MessageBox confirm: self displayString caption: 'The animal
you''re thinking of...')
ifTrue: [ self yes ask ]
ifFalse: [ self no ask ].
Pregunte>> pregunta "Pregunta la pregunta de receptor y continúa el juego dependiendo de apropiadamente la respuesta que se
recibe"
(MessageBox confirma: el ser displayString título: 'El animal usted'' re pensando en. ..') IfTrue: [el ser sí pregunta] ifFalse: [el ser no pregunta].
Nota: la cita doble '' las marcas que utilizaron para obtener un solo carácter de la cita dentro del String de texto de título. Usted debe utilizar éstos e indicar al compilador de Smalltalk que la String no deberá ser terminada realmente en este punto.
En el encima del método nosotros utilizamos un MessageBox para poner un diálogo sencillo que demuestra el texto de la pregunta juntos con un título conveniente y un par de botones para permitir al jugador para contestar sí o no. Optimistamente, usted ahora puede ver cómo que la lógica de juego sigue el sí o no, ramas en el árbol del conocimiento basado en la respuesta de jugador a la pregunta.
El siguiente es el Animal>>ask (Animal>> pregunta) el método. Cuándo esto se llama, la computadora piensa tiene una respuesta sensata para el animal (por lo menos no tiene más preguntas para preguntar de todos modos). Consecuentemente, debe preguntar si la respuesta es correcta y, si ése es el caso gana el juego. Si no, incita para que un Animal nuevo sea creado con la respuesta verdadera y para una Pregunta nueva que se distinguirá esto de la adivinación original. Usted advertirá que no hay mensajes nuevos a ser llamados que tenemos que diseñar mas métodos pero, no preocupa, por que llegaremos a éstos en apenas un momento.
Animal>>ask
"Ask whether the receiver is the animal that the player is thinking of.
If it is then the game is over. If it is not then prompt for the true answer
and install it and a question which will distinguish this new animal from
the receiver. This allows the game to learn."
| newAnimal newQuestion |
(MessageBox confirm: ('Are you thinking of ', self displayString, '?'))
ifTrue: [ MessageBox notify: 'I guessed your animal correctly.' caption: 'GREAT, I WIN' ]
ifFalse: [ newAnimal := Animal prompt. newQuestion := Question promptToDistinguish: self from: newAnimal ].
(MessageBox confirm: 'Do you wish to play again?' caption: 'I''m, getting better all the time...')
ifTrue: [ Animal playGame ].
El animal>> pregunta "Pregunta si el receptor es el animal que el jugador piensa. Si es entonces el juego está terminado. Si es no entonces incita para la respuesta verdadera y le instala una pregunta que se distinguirá a este animal nuevo del receptor. Esto le permite al juego aprender."
¿ | NewQuestion de newAnimal | (MessageBox confirma: (' Son usted pensando en ', el ser displayString, '?')) IfTrue: [MessageBox notifica: 'adiviné su animal correctamente.' título: 'GRAN, GANO'] ifFalse: [newAnimal: = aviso Animal. NewQuestion: = Pregunta promptToDistinguish: el ser de: newAnimal]. (MessageBox confirma: 'le Hace desea jugar otra vez?' título: 'I''m,
mejorándose todo el tiempo. ..') IfTrue: [playGame Animal].
Incitar para un Animal nuevo
Nosotros vimos en el último método una necesidad de tener la costumbre de crear un Animal nuevo incitando para su nombre. Bien aquí está.
Animal class>>prompt
"Prompt for a new animal to add to the game"
| newName |
[newName isNil or: [newName isEmpty]] whileTrue: [ newName := Prompter prompt: 'Tell me, what animal were you thinking of?
It was a...' caption: 'So, you win...'].
^self name: newName
La clase animal>> incita "Incita para un animal nuevo a añadir al juego"
¿ | NewName | [isNil de newName o: [isEmpty de newName]] whileTrue: [newName: = aviso más Pronto: 'me Dice, en qué animal usted pensaba? Era a. título de a. ..': 'así, usted gana. ..']. ^auto nombre: newName
Como usted puede ver que el uso de marcas de método de una clase llamó se apuntó, que se puede utilizar para incitar el usuario a entrar una String de texto. Esto se verifica para la validez y entonces utiliza para crear un caso Animal nuevo que utiliza su método original #name: method. (#el nombre: el método). Desde que el #prompt method (#el método) contesta una instancia nueva, tiene sentido para colocarlo en la categoría de creación de instancia. Recuerde también que es un método de la clase que debe tener la etiqueta de la Clase hecha clickeando en el browser cuando usted lo crea necesario.
Nota: El método es complicado levemente, por el hecho que tenemos que verificar que más Pronto contesta un nombre válido. Si nosotros no hicimos esto encontraríamos que el juego bastante pronto iría injustamente horrible.
Incitando para una Pregunta nueva
Y, casi finalmente, nosotros necesitamos un método de incitar para un objeto nuevo
de la Pregunta.
Question class>>promptToDistinguish: anOldAnimal from: aNewAnimal
"Answers an instance of the receiver (a Question) that will distinguish between
anOldAnimal and aNewAnimal. The question should be phrased such that the
answer is 'yes' for aNewAnimal"
| questionText |
[questionText isNil or: [questionText isEmpty]] whileTrue: [ questionText := Prompter prompt: ('Now, please enter a question that will answer Yes for ',
aNewAnimal displayString,
' and No for ', anOldAnimal displayString)
caption: 'Now, so I can learn about ', aNewAnimal displayString ].
^self text: questionText yes: aNewAnimal no: anOldAnimal
Pregunte la clase>> promptToDistinguish: anOldAnimal de: aNewAnimal "Contesta un caso del receptor (una Pregunta) eso se
distinguirá entre anOldAnimal y aNewAnimal. La pregunta se debe expresar tanto que la respuesta sea 'Y para aNewAnimal"
| QuestionText | [isNil de questionText o: [isEmpty de questionText]] whileTrue: [questionText: = aviso más Pronto: ('Now, entra por favor una pregunta que contestará Sí para ', aNewAnimal
displayString, ' y no para ', anOldAnimal displayString) título: 'Ahora, así
Animal class>>playGame "Start a new game using the existing knowledge base held in the KnowledgeBase class variable" MessageBox notify: 'Think of an animal and I will try to guess what it is. Are you ready?' caption: 'The Animal Game' . KnowledgeBase ask __
que puedo aprender acerca de ', aNewAnimal displayString]. ^auto texto: questionText sí: aNewAnimal no: anOldAnimal
Una vez más nosotros tenemos que utilizar un más Pronto el chequeo para ver que una respuesta válida se recibe del jugador antes de crear la instancia nueva.
Estamos ahora listos, con la adición de un último método, para jugar nuestro juego Animal. Lo qué necesitamos es un solo método de empezar el juego lejos.
Animal class>>playGame
"Start a new game using the existing
knowledge base held in the KnowledgeBase class variable"
MessageBox notify: 'Think of an animal and I will try to guess what it is.
Are you ready?' caption: 'The Animal Game' .
KnowledgeBase ask.
Así que ahora, para jugar el juego evalúa apenas:
PlayGame animal. Con un poco de suerte usted debe ser capaz de correr por unas pocas sesiones con el juego para que aprenda algunos animales nuevos. Hay una oportunidad bastante buena, sin embargo, algo puede haber fallado como usted trabajó este capítulo tan aquí está una lista de puntos de revisión.
El Chequeo de la lista de verificación de la emergencia
Usted tiene los siguientes métodos definidos:
Animal class>>initialize
Animal class>>name:
Animal class>>playGame
Animal class>>prompt
Animal>>ask
Animal>>displayOn:
Animal>>name
Animal>>name:
Animal>>printOn:
Question class>> promptToDistinguish:from:
Question class>>text:yes:no:
Question>>ask
Question>>displayOn:
Question>>no
Question>>printOn:
Question>>text
Question>>text:yes:no:
Question>>yes
La clase animal>> inicializa
la clase Animal>> el nombre:
la clase Animal>> playGame
la clase Animal>> incita
El animal>> pregunta
Animal>> displayOn:
Animal>> Animal
nombre>> el nombre:
Animal>> printOn:
Pregunte la clase>> promptToDistinguish: de:
la clase de la Pregunta> >text:yes:no:
Pregunte>> hace
Pregunta>> displayOn:
la Pregunta>> no Pregunta>> printOn:
la Pregunta>> la Pregunta
texto>
la Pregunta >text:yes:no:
la pregunta>> sí
También chequee que usted ha inicializado el juego evaluando:
Animal initialize
El animal inicializa
Encapsulando el juego
Animal hasta ahora usted acaba de utilizar el Package Browser para cargar paquetes existentes en su imagen de Dolphin. Desde que acabamos de crear lo que es efectivamente una aplicación nueva de Smalltalk nosotros quizás deseemos distribuir a otros, ahora es un tiempo oportuno aprender a cómo utilizar al Package Browser para crear un new package (paquete nuevo).
Abra el Package Browser que le mostrará los paquetes existentes en su sistema
Usted puede crear un paquete vacío nuevo escogiendo Package/New y entonces entrando un nombre apropiado de paquete. En este caso particular yo he escogido los "Animales" de nombre. Usted ahora puede escoger agregar las dos clases (Animal y Pregunta) y eso comprende el juego en uno de dos maneras.
Nota: de hecho, un paquete puede incluir objetos de otra manera que solamente clases. Por ejemplo usted puede incluir los métodos individuales en un paquete arrastrando los métodos del Class Hierarchy Browser y dejándolos caer sobre el paquete correcto en el Package Browser. Para más detalles aprieta F1 en tiempo dentro del Package Browser.
Crear un comentario de paquete.
Es usual incluir un comentario con el paquete que explica lo que es, para que es y cómo empezar a utilizarlo. Para hacer esta selecciona la etiqueta del Package comment y escribe un comentario apropiado en el panel del WorkSpace en el fondo del Package Browser. Puede guardar el comentario escogiendo el Workspace /Accept o presionando Ctrl + S.
Guardar el paquete
Después que usted ha creado un paquete nuevo o cambiado cualquiera de su contenido, que debe guardar para exportar las clases de su imagen. Si está a punto de guardar el paquete por primera vez, puede escoger una guía particular en la que el archivo de paquete (con. la extensión de PAC) residirá. Puede hacer utilizar el Package/Save (Paquete/guarda) como orden. Cuando quizás espere, en subsiguiente le guarda acaba de utilizar Package/Save o el Save el botón de la barra de herramientas para exportar el contenido.
Descargar un paquete de su imagen
Si desea quitar el juego Animal de la imagen de Dolphin lo que puede hacer es esto utilizando Package/Uninstall (Paquete/Desinstala) (pero usted debe saber esto ya).
RELOJ DIGITAL
Comenzar el funcionamiento del reloj. Copiar el Workspace. Seleccionar las
siete líneas y presiona "CTRL.+E"
relojDigitalProcess := [[ "Aquí le asignamos una variable"
Processor sleep: 1000. "Aquí le decimos que interrumpa al procesador"
(DesktopView current canvas) "En esta línea le decimos que pinte"
font: (Font name: 'Arial' pointSize: 36) bold; "En esta linea le decimos
que tipo de fuente va a utilizar"
text: Time now printString at: 30@10; "En esta linea le damos la ubicación
el N° 30 es el left y el 10 es el top"
free
] repeat] fork. "repita lo del corchete y el fork es el creador de procesos"
Lo que está con azul son las palbras reservadas, y en verde los comentarios.
Luego de haber seleccionado y ejecutado, tendra que aparecer un reloj así:
Cuando desees parar el reloj Copiar en el Workspace(donde ejecutaste los otros ejemplos anteriormente). Selecciona la línea y presiona "CTRL.+E"
relojDigitalProcess terminate. UserLibrary default invalidate: nil lpRect: nil bErase: true.
"En esta parte terminamos el proceso y borramos la pantalla
pintada"
Puedes probar ejecutando hasta invalidate y le pones un punto
y el resto lo borras y lo ejecutas con CTRL+D y veras que el reloj
se detiene pero no se borra la pantalla.
Para borrar la pantalla debes ejecutar toda la línea.
Ventana en Smalltalk
Para ejecutar se coloca el cursor en la línea donde está
la operación y se presiona es una pequeña demostración
de un paint "CTRL.+E"
scribble := Scribble show.
Volver |
---|
Lenguaje | Gramática | Autómata | Laplace | Series | Ecuación | Operador |
---|
Y para el cruel que me arranca
el corazón con que vivo,
cardo ni ortiga cultivo;
..cultivo una rosa blanca..!
José Martí
Amor | Sano | Asado | Alegria | Extasis |
Volver |
---|
Te espero en: wilucha@gmail.com
Esta page está en: www.wilocarpio.com.ar
24/09/2002