PINTURA DEL RENACIMIENTO EN ESPAÑA (SIGLO XVI).ppt
Introducción a la programación y la informática. Tema 4
1. Tema 4. Tipos de datos: clases y
referencias
Introducción a la Informática y a la Programación (IIP)
Curso 2011/12
Departamento de Sistemas Informáticos y Computación
2. Contenidos
1. Introducción
2. Ejemplo de definición y uso de una clase
3. Inicialización de los atributos
4. Representación en memoria de los objetos. Variables referencia
5. Diferencias entre variables elementales y objetuales
Declaración. Operador new
El operador de acceso "."
La asignación
Copia de objetos
Comparación de objetos
El garbage collector
6. Información de clase. Modificador static
07/10/2011 IIP - Curso 2011/12 2
3. Introducción
• En Java es posible utilizar elementos cuyos valores no son tipos primitivos.
• Un valor no perteneciente a un tipo primitivo es un tipo compuesto o
estructurado. Para definirlos en Java se utilizan las clases.
• Un elemento perteneciente a un tipo no primitivo, definido con una clase, es
un objeto.
• El valor de una variable objeto, debe entenderse como la agregación de los
valores individuales de sus componentes o atributos; estos podrán ser tanto
valores individuales como estructurados.
07/10/2011 3IIP - Curso 2011/12
// Crear un Circulo de radio 50, amarillo, con centro
// en (100,100)
Circulo c1 = new Circulo(50,"amarillo",100,100);
// Añadirlo a la Pizarra y dibujarlo
miPizarra.add(c1);
4. Introducción
Recordatorio de esquema de definición de una clase (tema 2):
[modificadores] class NombreDeLaClase [ extends OtraClase ] {
// Definición de atributos
[[modificadores] tipo nomVar1;
[modificadores] tipo nomVar2;
... ... ...
[modificadores] tipo nomVarN; ]
// Definición de métodos
// Constructores
... ... ...
... ... ...
// Otros métodos
}
07/10/2011 4IIP - Curso 2011/12
5. Ejemplo de definición y uso de una clase
• Se desea representar un punto en un espacio de dos dimensiones
(dos valores reales). Definición de la clase:
• Almacenado el código en un fichero (Punto.java) y tras haberlo
compilado, puede usarse para definir y utilizar variables de tipo
Punto en otra clase Java.
07/10/2011 5IIP - Curso 2011/12
class Punto {
double x; // la abscisa
double y; // la ordenada
// el constructor por defecto no es necesario
public Punto() { } //constructor por defecto
}
6. Ejemplo de definición y uso de una clase
07/10/2011 6IIP - Curso 2011/12
class PruebaPunto {
public static void main(String[] args) {
// se definen e inicializan dos variables de tipo Punto
Punto p1 = new Punto(); Punto p2 = new Punto();
// se asignan valores a los atributos de p1:
p1.x = 1.0; p1.y = 1.0;
// se asignan valores a los atributos de p2 usando p1:
p2.x = 2.0 * p1.x; p2.y = -2.0 * p1.y;
// se escriben los valores de los atributos de p2:
System.out.println("(" + p2.x + "," + p2.y +")");
}
}
7. Ejemplo de definición y uso de una clase
Algunas características, generalizables, de las clases de los ejemplos son:
• Mediante la operación new se crea un objeto de la propia clase. Después se
pueden utilizar los elementos del objeto: atributos y métodos.
• Los atributos de una clase pueden ser de cualquier tipo (elementales o no). Se
utilizan siguiendo las reglas de uso de las variables de dicho tipo.
• En el ejemplo se han definido sin modificador de acceso, esto se conoce como
acceso friendly: accesibles desde todas las clases del paquete en que se
encuentre la clase en que se definen.
– Pero habitualmente se definirán de acceso privado, private, por ocultación y seguridad.
• El uso de los elementos del objeto se hace utilizando la notación de punto. En
particular, a los atributos se les asigna o lee su valor utilizando:
07/10/2011 7IIP - Curso 2011/12
nombreDeVariableObjeto.nombreDeAtributo
8. Inicialización de los atributos
• Cuando el objeto se crea, sus atributos se inicializan por defecto:
– A cero los numéricos, al código cero los char y a false los boolean.
– A null, que representa la inexistencia, los objetos.
• Se les puede dar un valor inicial explícitamente, por ejemplo:
• También se pueden inicializar en los constructores (tema 5).
En todo caso, la secuencia de ejecución de la inicialización es:
07/10/2011 8IIP - Curso 2011/12
class Punto {
double x = 1.0; double y = 1.0;
public Punto() { }
}
Por defecto explícitamente en los constructores
9. Representación en memoria. Referencias
Cuando se crea un objeto y se asigna a una variable, el sistema le
asocia memoria dividiéndola en dos partes:
• Una parte asociada al objeto como tal, mediante la que se mantiene su
información (valores de atributos y métodos que se pueden aplicar).
– La zona del sistema en la que se guarda la memoria de los objetos que se crean
durante la ejecución se denomina montículo (heap).
• Otra parte de memoria se asocia a la variable con la que se nombra al objeto.
Mediante la misma, el sistema determina en ejecución dónde se encuentra el
objeto para poder actuar con él.
Cuando se crea un objeto, se dice que mediante la variable que da nombre al
objeto se referencia la zona de memoria donde se encuentra el objeto en sí.
Es habitual denominar a estas variables variables referencia.
07/10/2011 9IIP - Curso 2011/12
10. Representación en memoria. Referencias
Ejemplo:
07/10/2011 10IIP - Curso 2011/12
// Creación de un Punto por defecto (0.0, 0.0). Asignación de la
// referencia al objeto a la variable punto1
Punto punto1 = new Punto();
0.0
x 0.0
y
montículo
Memoria del sistema
punto1
11. Representación en memoria. Referencias
Algunas características de las referencias:
• Todos los objetos en Java se manipulan mediante referencias. Los únicos
elementos no referenciados son los valores elementales.
• Cuando una variable referencia no identifique ningún objeto; puede utilizarse
una constante especial para indicarlo: null.
• Si dos variables referencia mantienen un mismo valor, entonces ambas están
referenciando al mismo objeto.
• Los únicos operadores permitidos para manipular variables referencia son: de
asignación (=), de acceso (.) y comparaciones: (==, !=).
La principal diferencia entre valores primitivos y referencia consiste en que las
variables que representan a los primeros mantienen su valor, mientras que las
que representan a los segundos mantienen una referencia a los mismos.
07/10/2011 11IIP - Curso 2011/12
12. Diferencias: declaración, operador new
La declaración de un objeto no lo genera. Cuando se desea utilizar un nuevo
objeto de cierto tipo, es necesario crearlo.
Hasta el momento de su creación el objeto no existe y cualquier intento de
referenciarlo antes provocará un error de compilación o en tiempo de
ejecución.
07/10/2011 12IIP - Curso 2011/12
// Se declara circulo, que no referencia a ningún objeto
Circulo circulo;
// Se crea un Circulo y se asigna su referencia a circulo
circulo = new Circulo();
// Alternativamente: Se declara circulo y se le asigna la
// referencia al objeto Circulo que se crea
Circulo circulo = new Circulo();
13. Diferencias: declaración, operador new
07/10/2011 13IIP - Curso 2011/12
circulo
50.0radio
color
100centroX
100centroY
montículo
Memoria del sistema
“negro”
//Creación de un Circulo por defecto: radio 50, negro, en (100,100)
Circulo circulo = new Circulo();
14. Diferencias: el operador de acceso "."
El operador punto se emplea para seleccionar el método específico que se
desee utilizar sobre un objeto, por ejemplo:
y también para acceder a sus atributos:
Si se intenta utilizar un objeto inexistente, se producirá bien un error del
compilador, bien la excepción siguiente en ejecución:
07/10/2011 14IIP - Curso 2011/12
// creación de un objeto de tipo Pizarra
Pizarra miPizarra = new Pizarra("ESPACIO DIBUJO", 300, 300);
// creación de un objeto de tipo Circulo
Circulo circulo = new Circulo(50, "amarillo", 100, 100);
// uso del método add de la clase Pizarra
miPizarra.add(circulo);
Punto p1 = new Punto();
p1.x = -10.0;
NullPointerException
15. Diferencias: la asignación
La asignación entre variables referencia reemplaza las referencias, no el
contenido referenciado por las mismas.
07/10/2011 15IIP - Curso 2011/12
Punto p1 = new Punto(); // p1 referencia a un objeto
// de la clase Punto
Punto p2 = p1; // p1 y p2 referencian al
// mismo objeto
p2 0.0
x 0.0
y
montículo
Memoria del sistema
p1
16. Diferencias: la asignación
Considérese el ejemplo siguiente, en el que se pierde la referencia a un
objeto, se dice que el objeto queda desreferenciado.
07/10/2011 16IIP - Curso 2011/12
Punto p1 = new Punto(); // p1 referencia a un objeto
Punto p2 = new Punto(); // p2 referencia a otro objeto
p2 = p1; // p1 y p2 referencian al primer objeto,
// nada referencia al segundo
p2
0.0
x 0.0
y
montículo
p1 0.0
0.0
x
y
Memoria del sistema
17. Diferencias: copia de objetos
Si la estructura del objeto es conocida y accesible, entonces es posible
realizar una copia del mismo mediante una copia atributo a atributo.
Ejemplo, suponiendo que los atributos de Circulo fuesen accesibles (acceso
public o friendly en lugar de private como se declararon originalmente):
07/10/2011 17IIP - Curso 2011/12
// Crear un Circulo de radio 10, amarillo, con centro en (15,20)
Circulo c1 = new Circulo(10,"amarillo",15,20);
// se crea una copia:
Circulo copia = new Circulo();
copia.radio = c1.radio;
copia.color = c1.color;
copia.centroX = c1.centroX;
copia.centroY = c1.centroY;
18. Diferencias: copia de objetos
Nótese que el objeto String de valor "negro" queda desreferenciado.
07/10/2011 18IIP - Curso 2011/12
c1
montículo
Memoria del sistema
“amarillo”
10.0radio
color
15centroX
20centroY
10.0radio
color
15centroX
20centroY
copia
“negro”
19. Diferencias: comparación de objetos
• Para los tipos primitivos el operador "==" es cierto o falso según sean o no
iguales los valores de las variables que se comparan.
• Cuando este operador se aplica a objetos, devolverá cierto o falso según
sean o no iguales las referencias contenidas.
Si se aplica el operador a dos objetos distintos, aunque sus atributos
tengan el mismo valor, el resultado será false. Ejemplo:
07/10/2011 19IIP - Curso 2011/12
Punto p1 = new Punto();
p1.x = 3.0; p1.y = -2.5;
Punto p2 = p1;
Punto p3 = new Punto();
p3.x = 3.0; p3.y = -2.5;
System.out.println(p1 == p1);
System.out.println(p1 == p2);
System.out.println(p1 == p3);
true
true
false
20. Diferencias: comparación de objetos
• Si lo que se desea es determinar la igualdad interna de los objetos, es
necesario hacerlo mediante una comparación atributo a atributo:
• Como los atributos serán por lo general privados, se recurrirá a la definición
y uso de un método especializado, equals(), que existe, además,
predefinido en la clase Object.
07/10/2011 20IIP - Curso 2011/12
System.out.println(p1.x == p1.x && p1.y == p1.y);
System.out.println(p1.x == p2.x && p1.y == p2.y);
System.out.println(p1.x == p3.x && p1.y == p3.y);
true
true
true
21. Diferencias: el garbage collector
• Es un subsistema de la máquina virtual Java que recupera la memoria de los
objetos no referenciados para que pueda volver a ser utilizada.
• Es frecuente en los lenguajes actuales basados en el uso de una máquina
virtual (por ejemplo Java, C#, Python). En otros lenguajes (por ejemplo C++ o
Ada) es necesario que el programador libere explícitamente la memoria que
ha dejado de utilizarse.
• En Java entra en funcionamiento automáticamente, pero es posible
inhabilitar su funcionamiento, si se desea, o sugerir al sistema que se
ejecute mediante una utilidad de la clase System (System.gc()).
07/10/2011 21IIP - Curso 2011/12
22. Información de clase. Modificador static
En ocasiones es necesario mantener información común a todos los objetos
de una clase, por ejemplo:
• Número de objetos de la clase Punto que se han creado en un
momento dado.
• Número de objetos de la clase Circulo que existen de color
"amarillo".
• Número de objetos de la clase Circulo que se han creado y que han
cambiado su color de "negro" a "amarillo" .
La solución consiste en poder mantener información asociada a
toda la clase en conjunto.
Una variable o atributo de clase es una variable mediante la que es posible
mantener información común a todos los elementos de la clase.
07/10/2011 22IIP - Curso 2011/12
23. Información de clase. Modificador static
Se declaran precedidas del modificador static . Por ejemplo:
A efectos de su visibilidad, un atributo de clase, tiene el mismo
comportamiento que cualquier otro y puede declararse public, private o
friendly, tal y como es el caso.
07/10/2011 23IIP - Curso 2011/12
class Punto {
double x; // la abscisa, variable de instancia
double y; // la ordenada, variable de instancia
static int contador = 0; // variable de clase
// cada vez que se ejecute el constructor contador
public Punto() { contador++; } // se incrementa
}
24. Información de clase. Modificador static
Como no están asociados a ningún objeto (pertenecen a la clase):
• El sistema les asigna memoria la primera vez que se ejecuta código de la
clase, lo que puede ocurrir la primera vez que se crea un objeto de la
misma.
• La memoria asociada a las variables de clase permanece en uso hasta que la
clase deje de estar cargada en memoria, normalmente al finalizar el
programa que la utiliza.
• Si es accesible (no es privada), para referenciarlas desde otra clase se utiliza
la forma:
• Para el ejemplo anterior, sería:
07/10/2011 24IIP - Curso 2011/12
NombreDeClase.nombreDeAtributoDeClase
Punto.contador
25. Información de clase. Modificador static
Ejemplo, supuesta declarada la clase Punto:
07/10/2011 25IIP - Curso 2011/12
class PruebaPunto2 {
public static void main(String[] args) {
// se escribe el valor inicial del contador de Puntos,
// nótese que aún no se ha creado ningún objeto
System.out.println("Num. puntos inicial: " + Punto.contador);
// se definen e inicializan varias variables de tipo Punto
Punto p1 = new Punto(); Punto p2 = new Punto(); Punto p3 = new Punto();
int puntosCreados = Punto.contador; // puntosCreados vale 3
Punto.contador = 0; // se resetea el número
....
}
}
26. Información de clase. Modificador static
Un uso habitual de las variables de clase es usarlas para almacenar un valor
constante, común a todos los elementos de la clase. Ejemplo:
07/10/2011 26IIP - Curso 2011/12
public class Circulo {
private double radio; private String color;
private int centroX, centroY;
public static final double DOS_PI = 2 * Math.PI;
....
/** calcula el área del Circulo. */
public double area() { return Math.PI * radio * radio; }
/** calcula el perímetro del Circulo. */
public double perimetro() { return DOS_PI * radio; }
....
}