Técnicas Avanzadas de Programación. Contenido Conceptos generales de programación orientada a...
-
Upload
geraldo-chino -
Category
Documents
-
view
118 -
download
2
Transcript of Técnicas Avanzadas de Programación. Contenido Conceptos generales de programación orientada a...
Técnicas Avanzadas de Programación
Contenido Conceptos generales de programación orientada a objetos
Concepto de clase, método, mensaje, objeto
Ejemplo: un programa para manejo de Pozos
Ocultamiento de información
Algunos lenguajes orientados a objeto
Diseño orientado a objetos
Diseño dirigido por responsabilidades
UML (Lenguaje de modelado unificado - unified modeling language)
Contenido Mecanismos de reutilización de código
Herencia
Composición
Delegación
Tipos parametrizados
Enlace estático y dinámico
Asignación estática y dinámica de tipos
Enlace estático y dinámico de métodos
Contenido Herencia y tipos
Distribución de la memoria
Asignación y Equivalencia
Conversión de tipos
Herencia de clases y herencia de interfaces
Ocultamiento de información
Acoplamiento y cohesión
Control de acceso y visibilidad
Contenido Polimorfismo
Objetos polimórficos
Sobrecarga
Interfaces
Patrones de diseño
Estructura de un patrón de diseño
Patrones creacionales
Patrones estructurales
Patrones de comportamiento
Contenido Programación con hilos
Concurrencia y paralelismo
Hilos y procesos
Modelos de programación multihilos
Ciclo de vida de un hilo
Prioridades
Sincronización
Prácticas recomendadas
Acceso a bases de datos
JDBC
Conceptos Generales
Programación Orientada a Objetos Los especialistas ven la P.O.O. desde dos puntos de vista
El primero sostiene que la POO es una nueva forma de programar. Un nuevo paradigma
El segundo sostiene que la POO es simplemente una evolución de técnicas de programación ya existentes (tipos de dato abstractos)
Programación Orientada a Objetos La programación orientada a objetos como un nuevo paradigma de
programación
Programación Orientada a Objetos
ClaseAplicación
ClaseMenú
ClaseFactura
App Menu Factura
Emisor Receptor Receptor
Mensaje Mensaje
mostrar mostrar
Acción:muestra las opcionesdel menu
Acción:Imprime los datos dela factura
Programación Orientada a Objetos
Algunos conceptos básicos
Mensaje. Un mensaje es una solicitud de que se realice una acción. Se acompaña de cualquier información adicional (argumentos) necesaria para llevar a cabo la acción
Método. Es la acción que realiza el receptor de un mensaje para satisfacer la solicitud (un procedimiento)
Diferencias entre llamar a un procedimiento y pasar un mensaje:
Los mensajes tienen un receptor, los procedimientos no
La acción que se realiza en respuesta a un mensaje depende de quien recibe el mensaje
Programación Orientada a Objetos
La acción realizada en respuesta a un mensaje depende del receptor del mensaje
Menú
NuevoAbrirGuardarGuardar como
Mostrar
Factura
Fecha: 12/03/00Cliente: Pedro PérezCant. Descrip. Monto 1 Lavadora 5000,00 2 ...
Mostrar
Programación Orientada a Objetos Clases. Son categorías de objetos
Todos los objetos son ejemplares de una clase
El método invocado por un objeto en respuesta a un mensaje queda determinado por la clase del receptor
Todos los objetos de una clase usan un mismo método en respuesta a un mismo mensaje
Objetos. Son entes capaces de responder a un mensaje ejecutando una acción (método)
Los objetos tienen variables internas que determinan su estado. Las variables que tiene un objeto dependen de la clase pero los valores son particulares de cada objeto
Programación Orientada a Objetos Para programar en forma orientada a objetos es necesario:
Decidir que objetos se necesitan para resolver un problema
Determinar que métodos implementa cada clase
Si las clases requeridas no están disponibles será necesario diseñarlas
Diseñar una clase consiste en:
Establecer los métodos de la clase
Definir las variables internas o variables de estado que tendrán los objetos
Programación Orientada a Objetos
Ejemplo: un programa de manejo de cuentas de banco
En este ejemplo se presenta una clase Cuenta que puede ser el fundamento para un programa de manejo de cuentas
En primer lugar se presenta la definición de la clase, incluyendo la implementación de los métodos.
Luego se presenta la forma de utilizar la clase, es decir:
Como crear una Cuenta
Como pasar mensajes a una Cuenta
El ejemplo está implementado en Java
Programación Orientada a Objetos
Declaración de la clase Cuenta
package cuentas;
public class Cuenta {
private int id;
private String nombre;
private double saldo;
public Cuenta() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
setNombre(String nombre) {
this.nombre = nombre;
}
public double getSaldo(){
return saldo;
}
public void depositar(double
cantidad) {
this.saldo += cantidad;
}
public boolean retirar(double
cantidad) {
if (cantidad > this.saldo) {
saldo -= cantidad;
return true;
}
return false;
}
}
Programación Orientada a Objetos
Elementos que constituyen una clase
Declaración de la clase
Contiene el nombre de la clase y otros atributos
Variables
Las variables definen el estado del objeto
Métodos
Los métodos son procedimientos que se ejecutan cuando se pasa un mensaje a la clase
Constructores
Son procedimientos que permiten inicializar el objeto
Programación Orientada a Objetos
Como usar la clase Cuenta
// Como crear una cuenta
Cuenta c;
c = new Cuenta(3);
// Como pasar mensajes a una cuenta
c.depositar(10000);
int saldo = c.getSaldo();
System.out.println(saldo);
Programación Orientada a Objetos Estructura de un mensaje
c.setId(2);
mensajereceptordel mensaje
argumentos
Programación Orientada a Objetospublic class Carta {
public static final int ROJO=0;
public static final int NEGRO=1;
private int pinta;
private int valor;
public Carta(int p, int v) {
this.pinta = p;
this.valor = v;
}
public int getPinta() {
return this.pinta;
}
public int getValor() {
return this.valor;
}
public int getColor() {
if (pinta==CORAZON ||
pinta==DIAMANTE) {
return ROJO;
}
else {
return NEGRO;
}
}
}
Programación Orientada a Objetos La programación orientada a objetos como evolución de técnicas
preexistentes
Los programas se hacen más complejos en la medida que su tamaño aumenta
La complejidad se debe principalmente a la interconexión entre diferentes partes del programa
Técnicas para el manejo de la complejidad
Procedimientos.
Módulos.
Tipos de dato abstracto.
Programación orientada a objetos.
Programación Orientada a Objetos La programación orientada a objetos puede verse como una evolución de
los tipos de dato abstractos.
Tipo de dato abstracto: un tipo de dato definido por el programador.
Consiste de una estructura de datos y una serie de operaciones implementadas mediante procedimientos o funciones.
Las clases son un mecanismo o técnica de implementación de tipos de dato abstracto.
Al definir un TDA mediante clases se pueden especificar las operaciones válidas para el nuevo tipo de dato.
Esto permite al compilador verificar la validez de las operaciones al igual que para los tipos de datos predefinidos.
Programación Orientada a Objetos
struct pila {
int tope;
int valores[100];
};
void push(struct pila *p, int v) {
p->valores[++(ps->top)]=v;
return;
}
void pop(struct pila *p) {
if (empty(p)) {
/* error */
}
else {
return (p->valores[ps->top--]);
}
}
main()
{
struct pila p;
push(&p, 10);
x = pop(&p);
p.valores[5]=10; // bien
}
Ejemplo: implementación de una pila en C y C++
Programación Orientada a Objetos
public class Pila {
private int tope;
private int valores[100];
public Pila() {
tope = -1;
}
public void push(int v) {
valores[++top]=v;
return;
}
public int pop() {
if (empty(p)) {
/* error */
}
else {
return (valores[top--]);
}
}
}
Ejemplo: implementación de una pila en C y C++
public static void main(String[] args)
{
Pila p = new Pila();
p.push(10);
x = p.pop();
p.valores[5]=10 //error
}
Programación Orientada a Objetos Bjarne Stroustrup, creador del C++, prefiere el término tipo de
dato definido por el usuario al de clase
En lugar de Subclase habla de tipo de dato derivado
Los métodos son funciones miembro
En el diseño de un programa se pueden mezclar tipos definidos por el usuario con programación convencional (no orientada a objetos)
Los tipos definidos por el usuario son una herramienta más (aunque muy importante) entre las que el programador puede escoger para resolver problemas
Programación Orientada a Objetos
Encapsulamiento y ocultamiento de la información
Quién invoca un método de un objeto mediante un mensaje no tiene que saber lo que hace el objeto para satisfacer la solicitud
No se debe acceder directamente a las variables internas de un objeto
Los lenguajes de programación difieren en el soporte que dan al ocultamiento de la información
Programación Orientada a Objetos
Encapsulamiento y ocultamiento de la información
Cuenta c = new Cuenta();
c.id = 2;
En este ejemplo se esta modificando directamente una variable interna del objeto c. Esto no es recomendable
Si se cambia la implementación de la clase Cuenta, todas las partes del programa que contengan construcciones de este tipo deberán ser modificadas
Las variables internas de un objeto solo deben ser modificadas por el objeto mismo
Programación Orientada a Objetos
Encapsulamiento y ocultamiento de la información
La forma correcta de modificar el identificador de la cuenta es invocando un método diseñado para ese fin
Cuenta c = new Cuenta();
c.setId(2);
Programación Orientada a Objetos
Encapsulamiento y ocultamiento de la información
En Java existen modificadores que permiten determinar la visibilidad de los elementos de una clase:
private. Solo se puede acceder al elemento desde la clase en la cual está declarado
protected. Se puede acceder al elemento desde la clase, las subclases y el paquete
package. Se puede acceder al elemento desde la clase y cualquier otra clase que esté en el mismo paquete
public. Se puede acceder al elemento desde cualquier parte del programa
Programación Orientada a Objetos
Encapsulamiento y ocultamiento de la información
En general deben ser privados siempre:
Las variables de instancia
Métodos que son invocados por otros métodos de la misma clase y que no deben ser invocados externamente
Deben ser públicos
Los constructores y métodos que serán invocados por otras clases
Pueden ser públicos o privados
Las constantes
Programación Orientada a Objetos
Encapsulamiento y ocultamiento de la información
Pueden ser protected
Las variables de instancia que se sabe que serán accedidas por subclases de la clase en la cual está declaradas
Esto es controversial. Hay quienes sostienen que las subclases deben acceder a las variables de las superclases invocando métodos públicos o protegidos.
Cuando usar package
Package se puede usar en lugar de protected para permitir que subclases accedan a las variables de instancia de las superclases.
En ese caso las subclases deben estar en el mismo paquete
Programación Orientada a Objetos
Encapsulamiento y ocultamiento de la información
En C++
Existe private, public y protected
En smalltalk
No existen modificadores, todas las variables son privadas y todos los métodos son públicos
Programación Orientada a Objetos
Algunos lenguajes orientados a objetos
Smalltalk
Un lenguaje 100% orientado a objetos
El lenguaje incluye en su definición básica el mecanismo de mensajes
Todo lo demás se logra mediante una biblioteca de clases
No hay tipos de datos. Las variables no tienen tipo
Los valores que contienen las variables son objetos que pertenecen a una clase
Es un lenguaje interpretado, lo que lo hace menos eficiente que lenguajes compilados, tales como C y Pascal
Programación Orientada a Objetos C++, Object Pascal
Lenguajes híbridos que combinan programación convencional con P.O.O.
Las clases se implementan mediante un nuevo tipo de dato (class) similar a una estructura que permite definir, además de variables, una lista de métodos que constituyen el comportamiento de los ejemplares
El problema principal de estos lenguajes es la implementación de clases mediante tipos de dato. Esto causa problemas sobre todo en el manejo de la herencia
En general son más eficientes que los lenguajes 100% orientados a objetos
Programación Orientada a Objetos Java
Sintaxis similar al C++
Lenguaje fuertemente orientado a objetos. (No 100 %)
Lenguaje con tipos (por tanto presenta los mismos problemas que C++ y Object Pascal)
Existe una jerarquía de clases predefinida que incluye clases que representan los tipos de dato básicos (integer, float, etc)
Es un lenguaje interpretado. Menos eficiente que C++
Existen, sin embargo, compiladores “just in time”, que mejoran considerablemente la eficiencia
Diseño Orientado a Objetos
Diseño Orientado a Objetos El primer paso en el diseño orientado a objetos consiste en
determinar
Cuales son las clases que se necesitan para la solución de un problema en particular
Que acciones debe realizar cada clase
Como se relacionan las clases
Existen numerosas metodologías de diseño orientado a objetos
Presentamos un método conocido como “Diseño dirigido por responsabilidades”
Diseño Orientado a Objetos
Diseño dirigido por responsabilidades
Se hace una analogía entre las clases que se requieren para la solución de un problema y un grupo de personas que se reúnen para realizar una actividad
Cada clase corresponde a una persona
A cada persona se asignan una serie de responsabilidades
Toda acción que se debe realizar debe estar asignada a una persona (en caso contrario la acción no se realizará)
Diseño Orientado a Objetos
Nombre de la clase
Responsabilidades
Colaboradores
Para el diseño se recomienda usar fichas
Cada clase es descrita por separado en una ficha
Diseño Orientado a Objetos La lista de responsabilidades son todas las acciones que deberán
realizar los miembros de la clase
En última instancia las responsabilidades se convertirán en métodos de la clase
La lista de colaboradores está formada por aquellas clases en las cuales se puede apoyar una clase para realizar su trabajo
Al comienzo del diseño no se hace distinción entre clases y ejemplares
Diseño Orientado a Objetos Los nombres de las clases deben ser palabras pronunciables, que
describan claramente aquello a lo que se refieren
Se recomienda usar mayúsculas o el carácter de subrayado para separar las palabras. Ej. MenúPrincipal o menu_principal
Las abreviaturas deben ser claras
Se debe evitar el uso de números en los nombres
Diseño Orientado a Objetos Ejemplos de nombres de clase:
LeerValores // No recomendable. No es un sustantivo
// Los nombres de clases deben ser sustantivos
M20 // No sugiere lo que representa la clase
ManejadorCuentas // Nombre adecuado
manejador_cuentas // Nombre adecuado
Diseño Orientado a Objetos
Categorías de clases
Las clases se pueden agrupar en categorías según el tipo de responsabilidades que tienen
Clases manejadoras de datos
Fuentes de datos o pozos de datos
Clases de vista o visualización
Clases auxiliares
Diseño Orientado a Objetos
Clases manejadoras de datos
Son clases cuya responsabilidad principal es mantener cierta información
Por ejemplo en un juego de cartas la clase Carta es un manejador de datos
En un programa de contabilidad una clase Cuenta es un manejador de datos
Las clases manejadoras de datos generalmente son los bloques fundamentales de un diseño
Diseño Orientado a Objetos Los datos que pertenecen a una clase manejadora de datos solo
deben ser manipulados por su dueño (encapsulamiento)
Las demás clases no deben modificar o leer directamente los datos que pertenecen a un manejador de datos
Para tener acceso a la información deben solicitarlo mediante un mensaje a la clase dueña
Es un factor importante del diseño determinar cuales datos deben ser manejados por una clase manejadora de datos
Diseño Orientado a Objetos Únicamente el manejador de datos debe acceder a la información
que le pertenece
Manejadorde Cuentas
Archivode cuentas
ProcesadorTransacciones
leerCuenta(100)
ObtenerSaldo(100)
LeerCuenta(100)
ManejadorCuentas
Diseño Orientado a Objetos
Fuentes de datos de datos
Son clases que generan datos (por ej. un generador de números aleatorios), o los aceptan para realizar algún procesamiento
Los datos fluyen a través de la clase pero ésta no es dueña de los datos
Por ejemplo una clase Archivo que tiene como responsabilidades
Abrir un archivo en disco
Leer y escribir datos al archivo
Cerrar el archivo
Diseño Orientado a Objetos Una fuente de datos no es dueña de los datos
ManejadorCuentas
Archivode cuentas
Manejadorfacturas
LeerRegistro
ManejadorArchivos
LeerRegistro
Archivode facturas
Diseño Orientado a Objetos
Clases de vista o visualización
Son clases que permiten mostrar o visualizar información en un dispositivo de salida
Generalmente el código que realiza estas actividades es complejo, modificado frecuentemente e independiente de los datos que se muestran
Es recomendable separar el código de visualización del código de manejo de los datos
Cuando se tiene un manejador de datos y una clase de vista asociada se dice que el manejador de datos es el modelo y la clase visualizadora es la vista
Diseño Orientado a Objetos
Ejemplo:
La clase Pozo es un manejador de datos. Sus instancias representan o modelan pozos del mundo real
Un graficador de pozos tiene tiene una lista de pozos y se encarga de mostrar una gráfica con la información que ellos contienen
GraficadorPozos
Pozo
Manejadorde datos
Clase devisualización
Diseño Orientado a Objetos
Caso de estudio: Una aplicación de supervisión de pozos
Se tiene una base de datos con información histórica de pozos
Se desea crear una aplicación que permita visualizar una gráfica de la producción de crudo y gas de los pozos.
Diseño Orientado a Objetos
Clases
Un formulario mediante el cual se puede introducir una lista de las clases que se desea visualizar y las características del gráfico que se desea obtener
Una clase GraficadorPozos que se encarga de crear el gráfico con las características definidas por el usuario. Es una clase de visualización
Una clase Pozo que almacena la información de un pozo. Es una clase manejadora de datos
Una clase BaseDatos que hace acceso a la base de datos que contiene la información de los pozos
Diseño Orientado a Objetos Tarjeta CRC de la clase Formulario
Graficador Pozos
Formulario
Pedir al usuario la lista de pozos que se desean graficar
Solicitar al graficador de pozos que despliegue la gráfica
Diseño Orientado a Objetos Tarjeta CRC de la clase GraficadorPozos
PozoGraficadorPozos
Crear los pozos con los identificadores de pozos recibidos del Formulario
Solicitar a cada pozo la producción de crudo y de gas
Crear el gráfico con la información obtenida
Diseño Orientado a Objetos Tarjeta CRC de la clase Pozo
BaseDatosPozo
Leer los datos del pozo al cual representa
Mantener los datos del pozo
Devolver la producción de crudo y gas
Diseño Orientado a Objetos Tarjeta CRC de la clase BaseDatos
BaseDatos
Devolver la producción de crudo de un pozo dado el id del pozo
Devolver la producción de gas de un pozo dado el id del pozo
Diseño Orientado a Objetos Otro ejemplo: un programa para cajeros automáticos
El programa debe
Mostrar un mensaje de bienvenida a los usuarios
Esperar a que se introduzca una tarjeta
Leer el id de la cuenta de la tarjeta
Solicitar al usuario que introuzca la clave
Verificar si la clave es correcta
Presentar al usuario un menú de opciones (retiro, consulta, ...)
Realizar la operación solicitada y actualizar la cuenta
Entregar el dinero
Diseño Orientado a Objetos Tarjeta CRC de la clase LectorDeTarjetas
LectorDeTarjetas
Mostrar mensaje, esperar tarjeta
Pedir el Verificador de clave que compruebe validez
LLamar al selector de actividad
Devolver Tarjeta
VerificadorDeClave
SelectorDeActividad
Diseño Orientado a Objetos Tarjeta CRC de la clase LectorDeTarjetas
VerificadorDeClave
Recibir clave del ManejadorDeCuenta.
Verificar si existe la cuenta
Presentar ventana de solicitud de clave
Recibir clave del usuario
Comparar claves y devolver el resultado.
ManejadorDeCuenta
Diseño Orientado a Objetos Tarjeta CRC de la clase LectorDeTarjetas
ManejadorDeCuenta
Verificar validez de cuenta y devolver la clave
Verificar información de retiro y depósito.
ManejadorDeCuenta
Diseño Orientado a Objetos Tarjeta CRC de la clase LectorDeTarjetas
SelectorDeActividad
Mostrar menú de actividades
Esperar selección del usuario
Llamar al manejador de transacción apropiado
ManejadorDeDepósitos
ManejadorDeRetiros
Diseño Orientado a Objetos Tarjeta CRC de la clase LectorDeTarjetas
ManejadorDeRetiros
Preguntar al usuario cantidad del retiro Verificar la cantidad con el ManejadorDe
Cuenta Decirle a CajaElectrónica que descarge el
efectivo
ManejadorDeCuentas
ManejadorDeRetiros
CajaElectrónica
Diseño Orientado a Objetos Tarjeta CRC de la clase LectorDeTarjetas
CajaElectrónica
Dar efectivo Dar sobre de depósito Recuperar sobre de depósito
Diseño Orientado a Objetos
Unified Modeling Language (UML)
Es una notación para representar modelos orientados a objetos
A finales de la década de los 80 aparecieron varios métodos de modelado: Booch, Rumbaugh y Jacobson
UML es la unificación de estos métodos
Está en proceso de estandarización por ISO/ANSI
Diseño Orientado a Objetos Un modelo consiste de clases y objetos relacionados entre si, que
describen o representan un aspecto del mundo real
Para la descripción de un modelo en UML existen varios tipos de diagramas:
Diagramas de clases (modelo estructural)
Diagramas de objetos (modelo de interacción)
Diagramas de secuencia
Use cases (casos de uso)
Diseño Orientado a Objetos
Modelo estructural
Una vista de un sistema que hace énfasis en la estructura de los objetos, incluyendo sus clasificadores, relaciones, atributos y operaciones
Diseño Orientado a Objetos
Diagrama de clases
Un diagrama de clases contiene representaciones de clases y relaciones entre clases
Una clase se representan mediante un rectángulo dividido en tres áreas o bandas: banda de nombre, banda de atributos y banda de operaciones
Pozo
IdproducciónCrudoproducciónGas
devolverProducciónCrudodevolverProducciónGas
Diseño Orientado a Objetos Se utiliza también un diagrama simplificado de clases en el que se
omiten la segunda y tercera banda
En este caso la clase Pozo se representa como sigue
Pozo
Diseño Orientado a Objetos
Relaciones
UML permite definir varios tipos de relación entre clases. A continuación se enumeran algunos
Asociación
Agregación
Composición
Generalización
Diseño Orientado a Objetos
Asociaciones
Para representar relaciones de asociación entre clases se usan líneas para conectar las clases relacionadas
La multiplicidad sirve para especificar cuantos ejemplares de una clase se pueden asociar con un ejemplar de la otra clase
En el ejemplo un GraficadorPozos se puede asociar con 0 o más pozos (* denota 0..n)
Graficador
PozosPozo
1 *
tiene
Diseño Orientado a Objetos A continuación se presentan algunos ejemplos de multiplicidad
T
T
T
T
Cero o más (muchos)
Uno o más
Entre uno y 40
Exactamente 5
*
1..*
1..40
5
Diseño Orientado a Objetos Ejemplos adicionales
* 1..*
Contrato
Patrono Empleado
Empresa * Persona1..*
Patrono Empleado
Emplea
Empresa Persona
Diseño Orientado a Objetos
Agregación
Es un tipo especial de asociación que describe una relación todo-parte
Ejemplo
Universidad FacultadTiene
1..*
Diseño Orientado a Objetos Composición
La composición es un forma de agregación que implica una fuerte relación de propiedad
Avión
TrenAterrizajeFuselaje Motor
1 1 2
Diseño Orientado a Objetos Composición
Motor 2
Fuselaje 1
TrenAterrizaje 1
Avión
Diseño Orientado a Objetos
Generalización
Es una relación entre una clase general y una clase más específica
Ejemplo
Empleado
VendedorGerente
Diseño Orientado a Objetos Diagrama de clases UML correspondiente a la aplicación de
ejemplo
Graficador
PozosPozo
1 1..*
tiene
Formulario
Pozos
1
1tiene
BaseDatos
1
1
tiene
Diseño Orientado a Objetos Diagramas de secuencia
Verificar(noCta)
LectorTarjeta VerificadorClave
ManejadorCuenta
DevolverClave()
ManejadorTeclado
LeerClave()
Creación de objetos
Creación de objetos Una vez que se han definido las clases, el siguiente paso es crear
objetos
Al momento de arrancar el programa deberá crear uno o varios objetos iniciales (por lo menos uno)
Posteriormente los diferentes objetos que constituyen el programa pueden crear (y destruir) otros objetos
Por lo tanto la creación y destrucción de objetos es un proceso que se realiza durante toda la ejecución del programa
Cuando el programa finaliza el último paso debe ser destruir el objeto (u objetos) creado inicialmente
Creación de objetos Organización de la memoria de un programa
Memoria automática(Pila)
Memoria dinámica(Montículo – heap)
Memoria estática
Creación de objetos
Memoria automática
Conocida como la pila del programa
La memoria se asigna y libera automáticamente
Las variables se asignan cuando se ejecuta el bloque de código donde están declaradas
Por ejemplo, en C++ o Java
void graficar() {
int n;
Pozo p(10);
...
}
Creación de objetos
Memoria estática
Las variables estáticas se asignan cuando el programa arranca y se liberan cuando termina
Por ejemplo, en C++
Pozo pozo;
void graficar() {
static Pozo p(10);
static int x;
...
}
Creación de objetos
Memoria estática
Ejemplo en C y C++
void getNextNumber() {
static int number = 0;
number += 1;
return number;
}
void main()
{
int n;
for (n=0; n<5 ; ++n) {
printf("%d ", getNextNumber());
}
}
Creación de objetos
Memoria estática
Ejemplo en Java
class MyClass
{
public static int number = 0;
...
}
La variable se asigna al momento de cargar la clase (generalmente la primera vez que se usa)
Creación de objetos
Memoria dinámica
Los objetos son creados en memoria dinámica de manera explícita, es decir, el programador determina el momento exacto en que se debe crear el objeto.
Así mismo los objetos deben ser destruidos por el programador
Por ejemplo en C++
void graficar() {
Pozo *p;
p = new Pozo(2);
...
delete p;
}
Creación de objetos
En C++ se pueden crear objetos de varias maneras
Al declarar una variable de un tipo correspondiente a una clase
...
Pozo p(2); // se ha creado un pozo
En este caso el objeto se puede crear en memoria estáfica o dinámica
Se puede crear un objeto en memoria dinámica mediante el operador new
Pozo *p; // aquí no se ha creado el pozo
p = new Pozo(2); // se crea el pozo en memoria
// dinámica
Creación de objetos
Creación de objetos en Java
En Java los objetos siempre son creados en memoria dinámica
Sólo hay una forma de crear objetos
...
Pozo p; // Aquí no se ha creado el pozo
p = new Pozo(1); // Se crea el pozo en memoria
// dinámica
Los objetos son destruidos automáticamente mediante un recolector de basura
Creación de objetos En Java las referencias de los objetos y los valores de tipos
primitivos pueden ser almacenados en memoria automática
int getNextNumber() {
int next = 0;
return ++next;
} o en memoria estática
public class SequenceManager {
static int next = 0;
static int getNextNumber() {
return ++next;
}
}
Creación de objetos
Creación de objetos en Objective C
Los objetos siempre se crean en memoria dinámica
...
Pozo *p; // Aquí no se ha creado el pozo
p = [ Pozo alloc ]; // Se crea el pozo en memoria
// dinámica
Creación de objetos
Inicialización
Java y C++ tienen un mecanismo de inicialización automático conocido como constructores
Los constructores son métodos con el mismo nombre que la clase
...
class Cuenta
{
private:
int id;
...
public:
Cuenta();
Cuenta(int);
int getId();
void setId(int idCta);
...
};
Creación de objetos
Inicialización
...
Cuenta::Cuenta()
{
id = 0;
}
Cuenta::Cuenta(int idCta)
{
this->id = idCta;
}
Creación de objetos
Inicialización en Java
class Cuenta
{
private int id;
...
public Cuenta() {
}
public Cuenta(int idCta) {
this.id = idCta;
}
int getId() {
return this.id;
}
...
};
Creación de objetos
Inicialización en Java
También se pueden usar métodos de clase
class Cuenta
{
private int id;
...
private Cuenta() {
}
public static Cuenta crear(int idCta) {
Cuenta cta = new Cuenta();
cta.id = idCta;
}
...
};
Creación de objetos
Inicialización en Java
También se pueden usar métodos de clase
...
Cuenta c = Cuenta.crear(10);
...
Creación de objetos
Inicialización en Objective C
No hay constructores. Se usan métodos de inicialización y métodos de clase (factory methods)
@interface Cuenta : Object
{
int idCuenta;
char nombre[20];
double saldo;
}
+(Cuenta *) create: (int) id;
-(Cuenta *) init: (int) id;
...
Creación de objetos
Inicialización en Objective C
No hay constructores. Se usan métodos de inicialización y métodos de clase (factory methods)
+(Cuenta *) create: (int) idCta
{
Cuenta *c = [ [ Cuenta alloc ] init: idCta ];
return c;
}
-(Cuenta *) init: (int) idCta
{
self = [super init];
if ( self) {
[self setId: idCta];
}
return self;
}
Creación de objetos
Inicialización en Objective C
main()
{
Cuenta *c;
c = [ Cuenta alloc ] init: 10 ];
c = [ Cuenta create: 20 ];
[ c depositar: 1500.0 ];
...
}
Creación de objetos Objetos en el montículo y objetos en la pila
Asignación
Verificación de igualdad
Constructures de copia en C++
Mecanismos de Reutilización de Código
Mecanismos de Reutilización de Código
Herencia Composición
Mecanismos de Reutilización de Código
Herencia
Es posible que existan varias clases con características similares
Por ejemplo, en relación con un pozo de levantamiento artificial por gas (gaslift) es necesario conocer la presión del gas a la entrada del pozo
Esta información no es requerida para pozos de flujo natural
Por otra parte, los pozos de flujo natural y los de gaslift comparten características similares, tales como profundidad del pozo, producción de crudo, etc
Mecanismos de Reutilización de Código
Herencia
En este caso, en lugar de crear dos clases independientes, es posible definir una jerarquía de clases
Pozo
PozoFlujoNatural PozoGasLift
Mecanismos de Reutilización de Código
Herencia
Es posible construir jerarquías de clases más complejas
Número
Entero
EnteroCorto
Real Complejo
EnteroLargo
Mecanismos de Reutilización de Código
Herencia
Las subclases heredan las variables y métodos de las superclases (pero no los valores de las variables)
Las subclases pueden agregar nuevos métodos, y variables o redefinir los métodos existentes
Un objeto puede responder a un mensaje que no esté definido en su clase si el método está implementado en algunas de las superclases
Mecanismos de Reutilización de Código Clase Pozo
public class Pozo{ private int id; private double prodCrudo; private double prodGas; public void leerValores() { ... }
public double getProdCrudo() { return this.prodCrudo; }
public double getProdGas() { return this.prodGas; }}
Mecanismos de Reutilización de Código Clase PozoGasLift
public class PozoGasLift extends Pozo{ private double presionEntrada;
public void leerValores() { super.leerValores(); presionEntrada = ... }
public double getPresion() { return presionEntrada; }}
Mecanismos de Reutilización de Código
Herencia
Cuando se pasa un mensaje a un objeto, la búsqueda del método a ejecutar comienza por la clase del objeto
Si no se encuentra el método en la clase la búsqueda continúa hacia arriba en la jerarquía de clases hasta llegar a la raíz del árbol
Se ejecuta el primer método encontrado o, si no se encuentra ningún método, se produce un error
Mecanismos de Reutilización de Código
Ejemplo
PozoGaslift pozo;
pozo = new PozoGasLift();
// Se ejecuta el método devolver presión
// de la clase PozoGasLift
double presion = pozo.getPresion();
// Se ejecuta el método get producción
// de crudo de la clase Pozo
int prod = pozo.getProdCrudo();
// error, el método imprimir no está definido
pozo.imprimir()
Mecanismos de Reutilización de Código
Anulación y refinamiento de métodos
Una clase que hereda de otra puede:
Agregar nuevas variables o métodos
Redefinir o anular un método
Refinar un método
Mecanismos de Reutilización de Código Redifinir o anular un método
Esto ocurre cuando la subclase tiene un método con el mismo nombre que un método de la superclase
En el ejemplo anterior, el método leerValores() está definido en la clase Pozo, pero está siendo redefinido en la clase PozoGasLift
public void leerValores()
{
this.prodCrudo = ...
this.prodGas = ...
}
Mecanismos de Reutilización de Código Refinar métodos
Para refinar un método se incluye un método con el mismo nombre. La diferencia con respecto a la anulación es que el nuevo método llama al método correspondiente en la superclase
public void leerValores() {
super.leerValores();
this.presionEntrada = ...
}
Mecanismos de Reutilización de Código Refinar métodos
En C++
public void leerValores() {
Pozo::leerValores();
this->presionEntrada = ...
}
Mecanismos de Reutilización de Código
Categorías o tipos de herencia
Especialización
Es el uso más común de herencia
La clase derivada es más especializada que la superclase
EjemploNúmero
Entero
EnteroCorto
Real Complejo
EnteroLargo
Mecanismos de Reutilización de Código Especificación
Se desea garantizar que las clases mantengan una interfaz común
La clase paterna especifica el comportamiento que se debe implementar
Las clases hijas implementan ese comportamiento
Construcción
Construir un concepto a partir de otro
Ejemplo:
La clase GraficadorPozo puede ser subclase de la clase JComponent de Java Swing.
En muchos casos se puede usar composición en lugar de construcción
Mecanismos de Reutilización de Código
Generalización
Lo opuesto a la especialización
La subclase es más general que la superclase
Generalmente se usa cuando se trabaja con clases que no se pueden modificar o que no se desean modificar
En general se debe evitar este tipo de herencia
Ejemplo
Ventana
VentanaColor
Mecanismos de Reutilización de Código
Composición
La herencia es una relación estática entre clases
Cuando una clase hereda de otra la relación entre las dos clases no varía durante toda la vida del programa
Cuando hay una relación de composición un objeto de clase A tiene uno o más objetos de clase B.
Vehículo
Motor
Mecanismos de Reutilización de Código
Composición
public class Vehiculo {
String modelo;
String año;
Motor motor;
...
}
public class Motor {
String modelo;
int potencia;
...
}
Mecanismos de Reutilización de Código
Composición
La composición puede ser usada como técnica de reutilización de código, al igual que la herencia
Muchos problemas que pueden ser resueltos mediante herencia también pueden ser resueltos por composición
Ejemplo: La clase GraficadorPozos puede tener una variable de clase JComponent (composición) en lugar de ser subclase de JComponent.
El método graficar invoca métodos de la clase JComponent para mostrar la gráfica en pantalla
Mecanismos de Reutilización de Código
Composición
La composición es una relación dinámica
La clase a la que pertenece el valor de la variable puede cambiar en tiempo de ejecución
Esto permite mayor flexibilidad que la herencia ya que el comportamiento puede cambiar dinámicamente
Mecanismos de Reutilización de Código
Delegación
La composición tiene la siguiente desventaja
Cuando se usa herencia los métodos siempre pueden hacer referencia al objeto this (el receptor del mensaje).
Cuando se usa composición esto no es posible
La delegación es similar a la composición. Hay una clase receptora y una clase delegada
La clase receptora tiene un objeto (el delegado) en el cual delega ciertas responsabilidades
Cada método de la clase delegada toma un parámetro del tipo de la clase receptora. Este parámetro hace las veces del objeto this.
Enlace Estático y Dinámico
Enlace Estático y Dinámico Enlace (binding): vincular un nombre con el objeto que denota
static int n = 10; // C++
Un entero es asignado en algún lugar de la memoria.
La vinculación entre el nombre n y el objeto (el valor entero) se puede hacer:
En tiempo de compilación - enlace temprano (early binding). El ejemplo anterior
En tiempo de ejecución – enlace tardío (late binding).
int *n = new int(10); // C++
Las funciones o subrutinas también pueden tener enlace temprano o tardío
Enlace Estático y Dinámico
El enlace implica determinar
Donde está el objeto en la memoria
¿Qué es el objeto?. Para poder determinar:
La validez de las operaciones
Cómo se realizan las operaciones
int a, b, c;
c = a + b // suma de enteros
double x, y, z;
z = x + y; // suma de punto flotante
String a = “Hola” * x;
El enlace puede ser estático o dinámico
Enlace Estático y Dinámico
Enlance estático. Asignación estática de tipos (C++, Java, Objective
C, Object Pascal): Se asigna un “tipo” a cada variable.
int x;
El tipo se usa para
Determinar el conjunto de valores legales que pueden contener las variables
Determinar la validez y el significado de las operaciones.
Una variable es una “caja de bits”. El tipo es lo que le da el significado a los bits.
El enlace es temprano (en tiempo de compilación)
Enlace Estático y Dinámico
Enlace dinámico (Objective C, Smalltalk, Python, Ruby):
Las variables no tienen tipo. Ejemplo en Smalltalk:
| x y z |
Cada valor es un objeto que pertenece a una clase
x := 10.
x := Pozo new: 4.
Asociado a cada valor está la información de “a qué clase pertenece”
No existe la idea de ”asignación ilegal de valores”
El enlace es tardío (en tiempo de ejecución)
Enlace Estático y Dinámico El enlace estático presenta ciertas dificultades cuando se trabaja
con jerarquías de clases
Cuando se pasa un mensaje a un objeto el sistema de ejecución debe:
Verificar la validez de la operación
Determinar cual método se debe ejecutar para satisfacer la solicitud
Enlace Estático y Dinámico Ejemplo
Figura
RectánguloCírculo Línea
Enlace Estático y Dinámico
public class Figura { protected int x; protected int y; public Figura(int cx, int cy) { x = cx; y = cy; } public void moverA(int cx, int cy)
{ x = cx; y = cy; }}
Enlace Estático y Dinámico
class Circulo extends Figura{ protected int radio; public Circulo(int cx, int cy, int r) { super(cx, cy); radio = r; } void dibujar() { // dibujar el circulo }}
Enlace Estático y Dinámico
Ejemplo
Circulo c;
c = new Circulo(100, 100, 50);
c.dibujar(); // se ejecuta el método dibujar
c.imprimir(); // error, la operación imprimir
// no está definida para Circulos
Enlace Estático y Dinámico
Ejemplo
Figura f;
Circulo c = new Circulo(100, 100, 50);
f = c;
El tipo de “f” es Figura, pero el valor al cual se refiere es un Circulo
En este caso se dice que Figura es el tipo estático y Circulo es el tipo dinámico
Enlace Estático y Dinámico Si intentamos realizar una operación definida para círculos se
produce un error
f.dibujar();// error, esta operación no está
// definida para figuras
Esto se debe a que Java utiliza enlace estático de tipos para determinar la validez de las operaciones
El método dibujar no está definido en la clase Figura
Enlace Estático y Dinámico La solución es declarar en la clase figura todos los métodos que se
implementarán en las subclases
abstract class Figura {
private int x;
private int y;
public Figura(int cx, int cy) {
x = cx;
y = cy;
}
void moverA(int cx, int cy) {
x = cx;
y = cy;
}
void dibujar(){
// implemenado por las subclases
}
}
Enlace Estático y Dinámico Al declarar abstracto el método dibujar:
No se pueden crear objetos de clase figura
Cualquier subclase de Figura debe implementar el método o ser declarada abstracta
1. abstract class Figura { protected int x; protected int y; public Figura(int cx, int cy) { x = cx; y = cy; } void moverA(int cx, int cy) { x = cx; y = cy; } abstract void dibujar();
1. }
Enlace Estático y Dinámico
En Java
Se utiliza el tipo estático para determinar la validez de la operación
Se utiliza el tipo dinámico para determinar cual método se va a ejecutar para satisfacer la solicitud
En C++
Se utiliza el tipo estático para determinar la validez de la operación
La selección del método se puede hacer estáticamente o dinámicamente
En Objective C
Hay enlace estático al estilo de Java y dinámico al estilo de Smalltalk
Enlace Estático y Dinámico Enlace en C++
class Figura {
Private:
int x;
int y;
public:
Figura(int cx, int cy);
void moverA(int cx, int cy);
void dibujar(); // enlace estático
}
Enlace Estático y Dinámico Enlace en C++
class Figura {
Private:
int x;
int y;
public:
Figura(int cx, int cy);
void moverA(int cx, int cy);
virtual void dibujar(); // enlace dinámico
}
Enlace Estático y Dinámico En C++ se pueden declarar métodos abstractos
class Figura {
protected:
int x;
int y;
public:
Figura(int cx, int cy);
void moverA(int cx, int cy);
virtual void dibujar() = 0; // método abstracto
}
Polimorfismo
Polimorfismo El término polimorfismo se refiere a conceptos diferentes, pero
relacionados
Se habla de polimorfismo cuando un mismo nombre sirve para invocar operaciones diferentes
int a, b;
a = b + 5; // suma de enteros
float a, b;
a = b + 5.0; // suma de punto flotante
Un objeto polimórfico es una variable o argumento de función que puede tener valores de tipos diferentes durante la ejecución del programa
Polimorfismo La POO permite implementar de manera directa la primera
acepción de polimorfismo
El método que se ejecuta en respuesta a un mensaje depende de la clase del receptor
Rectangulo r;
Circulo c;
c.dibujar(); // se ejecuta Circulo::dibujar()
r.dibujar(); // se ejecuta Rectangulo::dibujar()
Polimorfismo Otro aspecto del polimorfismo: Funciones que pueden tomar
parámetros de cualquier tipo
Ejemplo
ordenar(x)
x puede ser un arreglo de cualquier cosa
Unicamente se requiere que los elementos de x respondan al mensaje mayor
x[i].mayor(y)
La respuesta sería un valor booleano que indique si el receptor es mayor que el parámetro.
El método mayor tambien es polimórfico (el parámetro “y” puede ser cualquier cosa)
Polimorfismo Esto es fácil en lenguajes de programación 100% orientados a
objetos tales como Smalltalk pero difícil de lograr en lenguajes con tipos, tales como C++ y Java
C++ y Java ofrecen características diseñadas para permitir, hasta cierto punto, objetos polimórficos
Objective C permite desarrollar al estilo de smalltalk (sin tipos estáticos) o al estilo de Java (con tipos estáticos)
Polimorfismo
Java
Interfaces
Una interfaz es una colección de definiciones de métodos sin las implementaciones.
Una interfaz define un protocolo que un objeto se compromete a implementar
Se dice que un objeto implementa una interfaz
Polimorfismo Suponga que se desea implementar un método imprimir que
imprime el valor que se le pasa como parámetro
void imprimir(int v)
{
System.out.println(v);
}
En este caso imprimir solo puede trabajar con valores enteros
Polimorfismo Para resolver este problema se define una interfaz
ObjetoImprimible:
interface ObjetoImprimible
{
String convertirEnCadena();
}
El método convertirEnCadena devuelve la representación del objeto como un string.
Polimorfismo Ahora se puede declarar el método imprimir como sigue:
void imprimir(ObjetoImprimible v)
{
String s = v.converirEnCadena();
System.out.println(s);
}
Polimorfismo Para crear un objeto imprimible la clase del objeto debe
implementar la interfaz ObjetoImprimible:
class Pozo implements ObjetoImprimible
{
...
public string convertirEnCadena() {
...
}
...
}
Polimorfismo Ejemplo: un programa de optimización
import java.util.Random;
interface FuncionObjetivo
{
double evaluar(double x);
}
public class OptimizadorMonteCarlo
{
FuncionObjetivo func;
int ciclos;
double puntoOpt;
Optimizador(FuncionObjetivo f, int c) {
func = f;
ciclos = c;
}
Polimorfismo Ejemplo: un programa de optimización
// Iterar por el numero de ciclos especificados
// y devolver el valor minimo obtenido
public double optimizar() {
double min = 100000;
Random rnd = new Random();
double v, p;
for (int n=0; n < ciclos; ++n) {
p = rnd.nextDouble()*10;
v=func.evaluar(p);
if (v < min) {
min = v;
puntoOpt = p;
}
}
return min;
}
Polimorfismo Ejemplo: un programa de optimización
// devolver el punto donde se encontro el valor mínimo
public double puntoOptimo() {
return puntoOpt;
}
}
public class Cuadrado implements FuncionObjetivo
{
public double evaluar(double x)
{
return x*x;
}
}
Polimorfismo Ejemplo: un programa de optimización
// Crear una función objetivo y un optimizador
Cuadrado cuadrado = new Cuadrado();
Optimizador optimizador = new Optimizador(cuadrado, 100);
// Realizar la optimización
valorOptimo = optimizador.optimizar();
puntoOptimo = optimizador.puntoOptimo();
Polimorfismo
Generics.
Los Generics en Java son clases o métodos cuyos tipos están parametrizados.
Volveremos a este tema después de haber visto templates en C++
Polimorfismo C++ ofrece las siguientes características que ayudan a definir
objetos polimórficos
Métodos estáticos y virtuales
Herencia múltiple
Patrones (templates)
Polimorfismo
Herencia múltiple
Una clase puede ser subclase de dos clases diferentes
Window
Clock
WindowWithMenuWindowWithBorder
Polimorfismoclass Window {
...
public:
Window(char *title);
virtual void draw();
};
class WindowWithBorder : public Window {
// cosas relacionadas con bordes
void ownDraw();
void draw();
}
class WindowWithMenu : public Window {
// cosas relacionadas con menus
void ownDraw();
void draw();
}
Polimorfismoclass Clock : public WindowWithBorder,
public windowWithMenu
{
// cosas relacionadas con relojes
void ownDraw () // dibujar agujas y numeros
void draw();
}
Polimorfismo
void WindowWithBorder::draw() {
Window::draw();
ownDraw();
}
void WindowWithMenu::draw() {
Window::draw();
ownDraw();
}
void Clock::draw() {
Window::draw();
WindowWithBorder::ownDraw();
WindowWithMenu::ownDraw();
}
Polimorfismo La herencia múltiple presenta problemas de ambigüedad cuando
dos superclases de una clase tienen métodos con el mismo nombre
C++ tiene reglas para resolver la ambigüedad
Polimorfismo En C++ se puede implementar el concepto de interfaz utilizando
herencia múltiple y métodos abstractos
class ObjetoImprimible {
virtual char *convertirEnCadena() = 0;
};
El método convertirEnCadena no se implementa puesto que es abstracto
Cualquier subclase de ObjetoImprimible debe implementar el método convertirEnCadena.
Polimorfismo Plantillas. Son clases parametrizadas
template<class T> class Pila { int tope; T datos[100]; public: Pila(); void push(T); T pop(); };
PolimorfismoTemplate<class T> void Pila<T>::push(T elem){ if (top == 100) exit(1); datos[tope] = elem; tope = tope + 1;}
Pila <int> pilaEnt;
pilaEnt.push(10);
Pila <float> pilaFloat;
pilaFloat.push(5.2);
Polimorfismo Existe una biblioteca de clases estandar basada en templates (STL:
standard template library)
Los templates resuelven el problema parcialmente.
La misma clase patrón se puede usar para implementar clases que almacenen diferentes tipos de datos, pero no para que un objeto contenedor pueda contener objetos de tipos diferentes.
Polimorfismo
Objective C
Enlace totalmente dinámico.
No hay tipos de dato
Una función o método puede recibir parámetros de cualquier tipo
La implementación de funciones polimórficas es directa
Programación propensa a errores
Programas difíciles de entender en el futuro
Tipos estáticos.
Similar al sistema de tipos de Java
Para implementar funciones polimórficas se pueden usar: interfaces (protocols en Objective C)
No hay clases parametrizadas
Polimorfismo
Genéricos en Java
Similar en concepto a los templates en C++
Muy diferente la implementación
public class ArrayList<V>
{
private V[] values;
public ArrayList() {
values = (V[]) new Object[DEFAULT_SIZE];
}
}
Polimorfismo
Genéricos en Java
Similar en concepto a los templates en C++
Muy diferente la implementación
public class ArrayList<V> {
...
public V get(int index) {
return values[index]
}
public void add(V value) {
}
}
Polimorfismo
Genéricos en Java
Uso
public class Test {
public static void main(String[] args) {
ArrayList<int> a = new ArrayList<int>();
a.add(1); // OK
a.add(new Integer(1)); // igual a la anterior
// autoboxing
a.add(“Hola”) // error
}
}
Diferencias entre los genéricos de Java y los Templates de C++
La definición de las clases template en C++ no se compilan. Se distribuyen como código fuente
Cuando se declara un objeto cuyo tipo es una clase template el compilador genera una clase con el código fuente de la clase template en la cual el tipo parametrizado se sustituye por el tipo suministrado en la declaración. Ejemplo
Pila<int> p = new Pila<int>;
El compilador genera la siguiente clase
class PilaInt {
int valores[100];
int pop();
...
Diferencias entre los genéricos de Java y los Templates de C++
Si se declara una variable con otro tipo
Pila<double> p = new Pila<double>;
El compilador genera una clase totalmente diferente a la anterior:
class PilaDouble {
double valores[100];
double pop();
...
Las dos clases son incompatibles desde el punto de vista de la programación orientada a objetos
Diferencias entre los genéricos de Java y los Templates de C++
La definición de las clases genericas en Java. Se compilan como cualquier otra clase. Los tipos parametrizados se sustituyen por Object. Esto lo llaman “type erasure” porque después que el programa está compilado no queda ninguna información del tipo
Cuando se declara una variable con un tipo simplemente se crea una instancia de la única clase existente. Ejemplo
Pila<int> p = new Pila<int>();
El compilador simplemente crea un objeto de tipo pila. Dado que el tipo de la pila es Object se le puede agregar cualquier cosa. El compilador verifica que no se le agregue algo diferente a int
Diferencias entre los genéricos de Java y los Templates de C++
Sin embargo se puede hacer lo siguiente:
Pila<int> p = new Pila<int>();
Pila p1 = p;
p.push(“Hola”);
En este caso el compilador produce una advertencia (warning) pero el programa compila
Diferencias entre los genéricos de Java y los Templates de C++
En conclusión las clases parametrizadas (template) en C++ producen clases cuyos tipos son verdaderamente enteros, dobles, etc., mientras que las clases genéricas en Java producen clases cuyo tipo es siempre Object
Las clases parametrizadas en C++ por lo tanto son más seguras (type safe) y más eficientes
Los diseñadores de los genéricos en Java justifican sus decisiones argumentando compatibilidad con programas escritos con versiones anteriores a Java 1.5