Estamos trabajando arduamente para mejorarlo.
Si desea colaborar, puede editarlo aquí: edit here (md).
Objetos
| sections in this chapter: |
|---|
| herencia |
| anulacin |
| recursin |
| objetos-de-tipo-clase |
El mundo de XOScript está lleno de una diversidad de objetos, que están disponibles para su programa desde el principio.
Además de ajustar y expandir objetos existentes, también puede crear nuevos objetos usted mismo simplemente enviando el mensaje nuevo . Supongamos que desea crear un objeto de factura que aplique una secuencia de numeración; en ese caso, primero necesitará un objeto de factura.
Si sabe que cada objeto deriva de otro objeto, que, a su vez, eventualmente se origina en el objeto raíz de todos los objetos llamado Objeto, debe elegir en cuál de esos otros objetos se basará su nuevo objeto. Su nuevo objeto hereda todas las propiedades del objeto en el que se basa, es decir, al que se envió inicialmente el mensaje nuevo. En este ejemplo, se prefiere un objeto bastante neutral, uno sin demasiadas propiedades heredadas. Esto ofrece una elección fácil, porque en ese caso el nuevo objeto puede basarse en el objeto raíz en sí mismo, que es Objeto. La notación del sistema de facturas deseado será entonces la siguiente:
>> factura := Objeto nuevo.
factura en: ['empezar'] hacer: {
mi numero := 0.
}.
factura en: ['numero'] hacer: {
mi numero añadir: 1.
<- mi numero copiar bruto.
}.
Utilice este objeto de la siguiente manera:
factura empezar.
Salida escribir: factura numero, detener.
Salida escribir: factura numero, detener.
El número de factura actual se almacena en el objeto, por eso se coloca una palabra clave propia delante de él. Esto se llama propiedad; más detalles a continuación. Algunas empresas prefieren tener el año incorporado en los números de factura. En este caso, puede crear un nuevo objeto de factura basado en un objeto de factura anterior, pero que ofrece la posibilidad de su usuario de ingresar un año específico:
>> factura-anual := factura nuevo.
factura-anual en: ['empezar:'] hacer: { :año
mi numero := año.
}.
Este objeto de factura de año se puede usar como:
factura-anual empezar: 202000.
Salida escribir: factura-anual numero, detener.
Salida escribir: factura-anual numero, detener.
No es necesario volver a escribir la implementación del mensaje número, ya que se hereda del objeto factura escrito anteriormente; en consecuencia, se puede reutilizar el código antiguo. XOScript carece de conceptos como clases y otros conceptos relacionados. Esto significa que los objetos solo pueden heredar de otros objetos, también conocido como herencia prototípica. Ahora, volvamos a las propiedades. Las propiedades de los objetos solo se pueden abordar desde dentro, por lo que otros objetos no pueden percibirlas. A diferencia de otros lenguajes de programación, todas las propiedades de los objetos son visibles exclusivamente para el objeto que ha creado la propiedad y para los objetos derivados.
Herencia
En el capítulo 2 se ha ilustrado que los objetos pueden basarse en otros objetos. De esta manera, se puede reutilizar el código escrito previamente para crear una jerarquía de objetos. Por ejemplo:
>> Animal := Objeto nuevo.
>> Perro := Objeto nuevo.
>> Caniche := Objeto nuevo.
En este caso, Perro hereda todo el comportamiento de Animal y, a su vez, el objeto Animal hereda todo el comportamiento de Objeto, el objeto raíz de todos los objetos.
Anulación
En el siguiente ejemplo se crea un nuevo tipo de secuencia: Combinación, en la que se garantiza que cada elemento sea único. Las funciones de la secuencia se reutilizan mediante herencia:
>> Combinación := Serie nuevo.
Combinación en: ['adjuntar:'] hacer: { :elemento
>> ver := yo encontrar: elemento.
ver falso: { yo adjuntar: elemento. }.
}.
>> colores := Combinación nuevo.
colores
adjuntar: ['rojo'],
adjuntar: ['verde'],
adjuntar: ['azul'],
adjuntar: ['rojo'].
Salida escribir: colores, detener.
Observe cómo el segundo rojo queda excluido de la serie: Ocasionalmente, puede ser necesario anular el comportamiento de un objeto. Por ejemplo, al sumar números y unidades de medida, se deben tener en cuenta. En el siguiente ejemplo, se crea el objeto Tamaño. Este objeto devuelve un número que, durante la suma, tiene en cuenta la unidad del número que se va a sumar. El objeto Número comprueba si se trata de pulgadas o pies. El código de programación podría parecerse al siguiente:
>> Tamaño := Objeto nuevo.
Tamaño en: ['es:'] hacer: { :número
número en: ['+'] hacer: { :número
>> unidad := numéro calificador.
>> factor := 1.
unidad
en-caso-de: ['pulgadas'] hacer: { factor := 0.0833. }.
>> respuesta := yo + (número * factor).
<- respuesta.
}.
<- número.
}.
Este número de tamaño se puede utilizar de la siguiente manera:
>> tablero := Tamaño es: 6 pies.
>> borde := Tamaño es: 50 pulgadas.
Salida escribir: tablero + borde, detener.
Esto se mostrará como:
En el ejemplo anterior, se está anulando el signo más. Tenga en cuenta que, finalmente, todavía se debe realizar la suma final, que, de hecho, tiene lugar en la siguiente línea:
>> respuesta := yo + (número x factor).
Ahora bien, ¿cómo entiende XOScript que este signo más se refiere a la lógica original de la suma? Por ejemplo, otra interpretación podría ser que XOScript enviará repetidamente el mismo mensaje al mismo objeto, lo que, a su vez, daría como resultado un bucle infinito. Claramente, esta no es la intención. Tan pronto como envíe un mensaje a un objeto, que ejecutaría exactamente el mismo código, XOScript se dará cuenta, en este caso, de que se trata del mensaje subyacente anulado. Por lo tanto, su programa estará automáticamente protegido contra esta forma de bucles infinitos.
Recursión
Sin embargo, cuando su objetivo sea, de hecho, ejecutar la misma tarea desde la tarea actual, será necesario enviar primero el mensaje de forma recursiva. En este caso, el resultado será un bucle infinito. Sin embargo, existen aplicaciones útiles para las tareas recursivas. Por ejemplo, supongamos que desea calcular el factorial de un número determinado. En ese caso, simplemente agregue el mensaje factorial a Número:
Número en: ['factorial'] hacer: {
>> respuesta := 1.
yo > 0 verdadero: {
>> anterior := yo.
>> siguiente := anterior - 1.
respuesta := anterior * siguiente recursivo factorial.
}.
<- respuesta.
}.
Esto requiere recursión. De hecho, la tarea que está conectada al mensaje factorial debe ser ejecutada nuevamente dentro de esa tarea. Por lo tanto, es necesario invocar la tarea factorial desde dentro de la tarea factorial misma. Como regla, XOScript evitará esta rutina, debido al riesgo de terminar en un bucle infinito. Por esta razón, es vital preceder el mensaje con la palabra recursivo. Esto se hace para que XOScript sepa que es tu intención ejecutar la misma tarea y que no cometiste ningún error. El siguiente bucle muestra los factoriales de los números del 1 al 10:
{ :x Salida escribir : x factorial , detener. } * 10.
Sin la palabra recursiva, solo se produciría la multiplicación inicial. La lista quedaría así:
Objetos de tipo clase
La creación de un objeto que se establece en un estado inicial determinado presenta un problema frecuente. Supongamos que se debe crear un objeto Rectángulo para calcular el perímetro y el área. Una posible notación sería:
>> Rectángulo := Objeto nuevo.
Rectángulo en: ['área'] hacer: {
<- mi longitud * mi ancho .
}.
Obviamente, establecer una longitud y un ancho es una condición previa. Para ese propósito, se pueden agregar los mensajes longitud: y ancho:
Rectángulo en: ['longitud:'] hacer: { :longitud
mi longitud := longitud.
}.
Rectángulo en: ['ancho:'] hacer: { :ancho
mi ancho := ancho.
}.
Este rectángulo se puede utilizar de la siguiente manera:
>> rectángulo := Rectángulo nuevo longitud: 2, ancho: 3.
Salida escribir: rectángulo area.
Sin embargo, si se pasan por alto los ajustes iniciales de longitud y ancho, aparecerá un mensaje de error.
>> rectángulo := Rectángulo nuevo.
Salida escribir: rectángulo area .
Para evitar esto, es preferible que un rectángulo siempre tenga una longitud y un ancho iniciales, por ejemplo 0. Por lo tanto, en este caso, es necesario anular el mensaje nuevo.
Rectángulo en: ['nuevo'] hacer: {
>> rectángulo := yo nuevo.
rectángulo longitud: 0.
rectángulo ancho: 0.
<- rectángulo.
}.
Observe que en la segunda línea se vuelve a invocar el primer nuevo inicial. Sin embargo, esto no resultará en un bucle infinito, ya que XOScript lo evitará. Cuando se crea un nuevo rectángulo, ahora medirá automáticamente 0 por 0, desde el principio. De esta manera, no se producirá ningún error al calcular el área:
>> rectángulo := Rectángulo nuevo.
Salida escribir: rectángulo area.
>> rectángulo := Rectángulo nuevo longitud: 2, ancho: 3.
Salida escribir: rectángulo area.