Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Programación Orientada a Objetos: Introducción y Ejemplos en MzScheme, Apuntes de Semántica de Lenguajes de Programación

Programacion orientada a objetos

Tipo: Apuntes

2019/2020

Subido el 01/10/2020

gustavo-infante
gustavo-infante 🇻🇪

2 documentos

1 / 13

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Tema 11: Programación orientada a
objetos
Índice
1La Programación Orientada a Objetos...............................................................................2
1.1 Características principales.............................................................................................2
1.2 Historia de la Programación Orientada a Objetos.........................................................3
1.3 Programación Orientada a Objetos en MzScheme........................................................3
2Objetos y clases..................................................................................................................3
3Herencia............................................................................................................................. 6
4Interfaces............................................................................................................................8
5Funciones de bajo nivel de acceso a los campos............................................................. 10
6Definición de clases y modelo de entornos......................................................................10
7Referencias.......................................................................................................................12
Copyright © 2006 Depto. CCIA, Universidad de Alicante All rights reserved.
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Vista previa parcial del texto

¡Descarga Programación Orientada a Objetos: Introducción y Ejemplos en MzScheme y más Apuntes en PDF de Semántica de Lenguajes de Programación solo en Docsity!

Tema 11: Programación orientada a

objetos

  • 1 La Programación Orientada a Objetos............................................................................... Índice
    • 1.1 Características principales.............................................................................................
    • 1.2 Historia de la Programación Orientada a Objetos.........................................................
    • 1.3 Programación Orientada a Objetos en MzScheme........................................................
  • 2 Objetos y clases..................................................................................................................
  • 3 Herencia.............................................................................................................................
  • 4 Interfaces............................................................................................................................
  • 5 Funciones de bajo nivel de acceso a los campos.............................................................
  • 6 Definición de clases y modelo de entornos......................................................................
  • 7 Referencias.......................................................................................................................

1. La Programación Orientada a Objetos

En este tema vamos a introducir el paradigma de Programación Orientada a Objetos (POO),

incidiendo en sus aspectos fundamentales. Vamos a utilizar de nuevo el lenguaje de

programación Scheme (en concreto la librería class.ss de la implementación MzScheme)

para resaltar los elementos esenciales de la POO que son comunes a los distintos lenguajes de

programación orientados a objetos (Java, C#, C++, etc.).

1.1. Características principales

Una de las ideas fundamentales del paradigma de programación orientada a objetos es el

concepto de objeto como una entidad que engloba datos y funciones.

En programación funcional el elemento principal que determina el funcionamiento de un

programa son las funciones. Las funciones transforman datos, los cuales sólo tienen

posibilidad de existir como valores que se pasan a una función o que son devueltos por ella.

Pero ahí termina su existencia. No tienen vida fuera de las funciones.

En programación imperativa, por otra parte, los datos se pueden considerar los elementos

fundamentales de un programa. Existen por si mismos y son usados y modificados por las

funciones. La posibilidad de la programación imperativa de mantener y modificar un cierto

estado (datos, valores de las variables) la hace muy potente para representar y modelar

procesos del mundo real que serían complicados de expresar en forma de programación

funcional. Las funciones son utilizadas para modificar el estado del programa.

Sin embargo, es posible un enfoque distinto que agrupe datos y funciones. Se trata del

utilizado en el paradigma de Programación Orientada a Objetos (POO). En este enfoque, el

concepto fundamental es el de objeto. Un objeto es una entidad con un estado (datos o

variables de instancia ) y unas funciones ( métodos ) que pueden acceder y modificar este

estado. Para evaluar las funciones hay que enviar un mensaje al objeto solicitando que se

ejecute alguno de sus métodos. Sólo es posible consultar el estado de un objeto mediante

alguno de sus métodos. De esta forma, en POO se refuerza la filosofía de la barrera de

abstracción y de la ocultación de información.

El enfoque de la POO permite modelar un dominio (problema a programar, un simulador de

deportes, por ejemplo) de una forma muy cercana a la realidad. Los objetos del programa

simulan los objetos (sustantivos) del dominio (por ejemplo, bicicleta, marchas, carretera,

etc.). Y los métodos de los objetos permiten modelar perfectamente las acciones (verbos, por

ejemplo cambiar de marcha, pedalear, etc.) que pueden realizar.

Entre las características de la POO podemos indicar los siguientes conceptos:

Page 2

(persona-nombre p1) -> "Rafa" (persona-fecha-nacimiento p1) -> "1988-03-25" (set-persona-fecha-nacimiento! p1 "1988-04-25")

Supongamos que queremos calcular la edad de una persona... la tenemos que definir como

una función aparte.

(define (edad persona fecha-actual) (let ((año-nacimiento (string->number (substring (persona-fecha-nacimiento persona) 0 4))) (año-actual (string->number (substring fecha-actual 0 4)))) (- año-actual año-nacimiento)))

(edad p1 "2006-05-23")

para obtener la fecha actual:

(require (lib "date.ss")) (date-display-format 'iso-8601) (define fecha-actual (date->string (seconds->date (current-seconds))))

(edad (persona-fecha-nacimiento p1) fecha-actual)

Vamos a hacer esto con Programación Orientada a Objetos

(require (lib "class.ss"))

Los primeros elementos que vamos a ver de POO:

  • Cómo definir una clase: campos y métodos
  • Cómo crear instancias de una clase
  • Paso de mensajes: cómo ejecutar métodos de las instancias

Definimos una clase persona% que tiene como campos de inicialización el nombre y el dni

y como resto de campos apellidos y fecha-nacimiento. Definimos los métodos di-hola y

edad que podrán ser ejecutados por objetos ; de esta clase.

Una clase es (al igual que una estructura) una plantilla donde se define un conjunto de

campos (también llamados en POO variables de instancia) y un conjunto de métodos

(funciones) que podrán ser ejecutadas por los objetos de esa clase. Las estructuras sólo

contienen datos, no métodos.

Otra diferencia importante es que las clases deben definir valores por defecto de los campos,

y que es posible diferenciar entre campos de inicialización y el resto de campos.

Todas las clases son hijas de la clase object% (ya hablaremos más adelante de la herencia).

Versión inicial y simplificada de persona

Page 4

(define persona% (class object% (init-field nombre nif) (field (apellidos null) (fecha-nacimiento null))

(define/public (di-hola) (printf "Hola, soy ~a~%" nombre))

(super-new)))

Creamos un objeto de tipo persona% (instanciamos un objeto) indicando los valores

iniciales de los campos nombre y nif:

(define p1 (new persona% (nif '212121232) (nombre "Pepito")))

Pedimos que ejecute el método di-hola

(send p1 di-hola)

Ejemplo completo

(define persona% (class object% (init-field nombre nif) (field (apellidos null) (fecha-nacimiento null))

(define/public (set-apellidos nuevos-apellidos) (set! apellidos nuevos-apellidos))

(define/public (set-fecha-nacimento fecha) (set! fecha-nacimiento fecha))

(define/public (get-nombre-completo) (if (not (null? apellidos)) (string-append nombre " " apellidos) nombre))

(define/public (di-hola) (define nombre-completo (send this get-nombre-completo)) (printf "hola, soy ~a~%" nombre-completo))

(define/public (get-edad fecha-actual) (let ((año-nacimiento (string->number (substring fecha-nacimiento 0 4))) (año-actual (string->number (substring fecha-actual 0 4)))) (- año-actual año-nacimiento)))

(super-new)))

(define p1 (new persona% (nombre "Rafa") (nif '23434222N)))

Page 5

La herencia facilita la reutilización de código y la abstracción.

Recordamos la clase anterior, con unas pequeñas variaciones:

(define persona% (class object% (init-field nombre) (field (amigos '()))

(define/public (di-hola) (printf "hola, me llamo ~a~%" nombre))

(define/public (get-nombre) nombre)

(define/public (es-amigo? otro) (if (memq otro amigos) ;memq comprueba si otro está en amigos usando la igualdad eq? #t #f))

(define/public (añade-amigo otro) (if (not (es-amigo? otro)) ; tambien es posible llamar a los métodos directamente (begin (set! amigos (cons otro amigos)) (send otro añade-amigo this))))

(define/public (saludan-amigos) (for-each (lambda (f) (send f di-hola)) amigos))

(super-new)))

(define frodo (new persona% (nombre "Frodo"))) (define gandalf (new persona% (nombre "Gandalf"))) (send frodo añade-amigo gandalf) (send frodo saludan-amigos) (send gandalf saludan-amigos)

Definimos la clase mago% que extiende la clase persona%

(define mago% (class persona% (init-field nombre-pila nivel-conjuro) (field (energia 100) (vida #t)) (inherit-field nombre)

(define/public (get-nivel-conjuro) nivel-conjuro)

(define/public (get-energia)

Page 7

energia)

(define/public (rayo) (set! energia (- energia 10)) (if (< 0 energia) (set! vida #f)))

(define/public (lanza-conjuro otro-mago) (define otro-nombre (send otro-mago get-nombre)) (define nivel-otro (send otro-mago get-nivel-conjuro)) (printf "Yo, ~a, lanzo un conjuro a ~a~%" nombre otro-nombre) (if (< nivel-otro nivel-conjuro) (begin (send otro-mago rayo) (printf "Mi conjuro te ha alcanzado, ~a~%" otro-nombre)) (printf "~a, admito que eres más poderoso que yo" otro-nombre)))

Inicializo superclase pasando un nombre construido a partir del nombre de pila:

(super-new (nombre (string-append "Mago " nombre-pila))))) (define gandalf (new mago% (nombre-pila "Gandalf") (nivel-conjuro 100))) (define saruman (new mago% (nombre-pila "Saruman") (nivel-conjuro 90))) (send gandalf lanza-conjuro saruman) (send saruman lanza-conjuro gandalf)

Definimos la clase enano% que extiende persona% y redefine el saludo

(define enano% (class persona% (inherit-field nombre)

(define/override (di-hola) (printf "Mmmm.. soy ~a y estoy hambriento!~%" nombre))

(super-new)))

(define gimli (new enano% (nombre "Gimli"))) (send frodo añade-amigo gimli) (send frodo saludan-amigos)

4. Interfaces

Las interfaces definen un conjunto de métodos sin especificar su implementación. Cuando

una clase implementa una interfaz debe especificar todos los metodos contenidos en ella.

Para definir una clase que implementa una interfaz hay que usar la palabra clave class*

Page 8

(define i-extended-stack% (interface (i-stack%) size))

(define extended-stack% (class* safe-stack% (i-extended-stack%) (inherit-field stack)

(define/public (size) (length stack))

(super-new)))

5. Funciones de bajo nivel de acceso a los campos

La función (get-field field objeto) devuelve el valor de un campo publico

(get-field name s1) (get-field stack s1)

Se pueden obtener selectores y mutadores de los campos accediendo a la clase con las

funciones

(class-field-accessor clase campo) -> devuelve un selector (class-field-mutator clase campo) -> devuelve un mutador

Ejemplos:

(define name-mutator (class-field-mutator stack% name)) (define name-selector (class-field-accessor stack% name)) (name-mutator s1 'pepito) (name-selector s1) (get-field name s1) (send s1 print-name)

Funciones auxiliares (reflexión):

(object? v) (class? v) (interface? v) (class->interface class) (object-interface object) (is-a? v interface) (is-a? v class) (subclass? v class) (implementation? v interface) (interface-extension? v interface) (interface->method-names interface) (field-names object)

6. Definición de clases y modelo de entornos

Page 10

La programación orientada a objetos en Scheme amplía el modelo de entornos, añadiendo

nuevas funcionalidades que no se pueden explicar directamente con ese modelo.

Sin embargo, es posible utilizar las características del modelo de entornos en la POO.

Por ejemplo, la definición de clases funciona de forma similar a la definición de funciones,

en el sentido de que todos los objetos creados una clase pueden acceder a las variables (datos

y funciones) del entorno en el que se creo la clase. Esto hace posible la creación de

VARIABLES DE CLASE, variables que sólo son accesibles desde los objetos de una clase, y

que son compartidas por todos ellos.

Veamos un par de ejemplos

Definimos la variable pi y la función square en el entorno global:

(define pi 3.14159) (define (square x) (* x x))

Definimos una clase que usa la variable y la función. Los objetos de esa clase pueden acceder

a ambas.

(define circulo% (class object% (init-field (radio 0)) (define/public (area) (* pi (square radio))) (super-new)))

(define circ1 (new circulo% (radio 10))) (send circ1 area)

Ejemplo contador (mal construido, porque la variable total está en el entorno global)

(define total 0) (define contador% (class object% (init-field (c 0)) (define/public (inc) (set! c (+ 1 c)) (set! total (+ 1 total)) c) (define/public (get-total) total) (super-new)))

(define c1 (new contador%)) (define c2 (new contador%)) (define c3 (new contador%)) (send c1 inc) (send c1 inc)

Page 11

Chicago.

Page 13