Introduccin a Java II - PowerPoint PPT Presentation

1 / 37
About This Presentation
Title:

Introduccin a Java II

Description:

abstract public double getArea(); Las clases hijas deben implementar el m todo abstracto ... public Circulo( double nuevoRadio, int posicionX, int posicionY ) ... – PowerPoint PPT presentation

Number of Views:144
Avg rating:3.0/5.0
Slides: 38
Provided by: r00021
Category:
Tags: dbl | introduccin | java

less

Transcript and Presenter's Notes

Title: Introduccin a Java II


1
Introducción a Java (II)
2
Índice
  • Introspección
  • Introducción a las relaciones
  • Herencia
  • Agregación

3
Introspección
4
Introducción
  • Java tiene interesantes mecanismos para obtener
    información interna de las clases, es decir, los
    objetos Java pueden informarnos de su propia
    estructura. Por ello se llaman utilidades de
    introspección
  • Vamos a centrarnos en lo fundamental de la
    introspección un objeto o una clase puede
    informarnos de la clase a la que pertenece
  • La clase más importante es java.lang.Class. Es
    una clase que nos permite describir cualquier
    clase Java. Dicho de otra forma, es un descriptor
    o referencia de una clase.
  • Un paquete relevante es java.lang.reflect

5
Conocer el tipo
  • En tiempo de ejecución puede saber el tipo
    (clase) que manejamos
  • Si tenemos un objeto, puedo conocer su clase
  • Coche miCoche new Coche()
  • Class clase miCoche.getClass()
  • System.out.println("Clase" clase.getName() )
  • Lo que hemos hecho es obtener un descriptor de
    clase (tipo Class) mediante miCoche.getClass().
    Este descriptor nos devuelve su nombre mediante
    getName()
  • Si tenemos una clase (no hay instancias)
  • Coche.class.getName()
  • getName() nos devuelve el nombre de la clase,
    incluyendo la jerarquía de paquetes. En nuestro
    ejemplo
  • newInstance.dominio.Coche

6
newInstance()
  • Podemos cargar de manera dinámica un objeto, es
    decir, determinar en tiempo de ejecución (y no en
    tiempo de programación) la clase que vamos a
    instanciar
  • Primero haremos una pequeña clase (Coche) de
    prueba
  • package newInstance.dominio
  • public class Coche extends Vehiculo
  • private int plazas 5
  • public Coche()
  • public Coche( int plazas ) this.plazas
    plazas
  • public int getPlazas() return plazas
  • public void setPlazas( int p ) plazas p
  • public String toString()
  • try return super.toString() " Plazas"
    String.valueOf(plazas)
  • catch (Exception e) return "-1"
  • A continuación crearemos un objeto del tipo
    Class, que es un descriptor de la estructura de
    datos o clase. Lo conseguimos con forName(). El
    paso siguiente es crear una instancia de la clase
    con newInstance().
  • Class clase Class.forName( newInstance.dominio.
    Coche )
  • Object objeto clase.newInstance()
  • System.out.println(Coche" objeto.toString()
    )

7
Introducción a las relaciones
8
Introducción (I)
  • Estamos acostumbrados a ver que diferentes tipos
    de objetos (naturales o artificiales) se
    relacionan, por ejemplo en una fabrica,
    universidad o un despacho de abogados
  • Con las clases ocurre algo parecido, se
    relacionan entre si. Los dos tipos fundamentales
    de relaciones son
  • Relación de clasificación o herencia (jerarquía
    de tipos).
  • Relación de agregación (jerarquía de partes)

9
Introducción (II)
  • La relación de clasificación o herencia es
    bastante común. Un autobús o un camión son tipos
    de vehículo, del mismo modo que un ingeniero o un
    contable son tipos de empleados. Las subclases
    (como el autobús o el camión) tienen atributos
    comunes, por el hecho de ser tipos de la clase
    vehículo. También decimos que heredan atributos
    de su superclase

Vehículo marca modelo precio ...
Camión cargaMax
Autobús plazas
Además heredan Marca, Modelo y precio
Lo que no significa que toda clasificación sea
sensata. Borges habla de una enciclopedia china
donde está escrito que los animales se dividen
en a) pertenecientes al emperador b)
embalsamados c) amaestrados d) lechones e)
sirenas f) fabulosos g) perros sueltos h)
incluídos en esta clasificación i) que se agitan
como locos j) innumerables k) dibujados con un
pincel finísimo de pelo de camello l) etcétera.
m) que acaban de romper el jarrón n) que de lejos
parecen moscas (El idioma analítico de John
Wilkins, Otras inquisiciones, Emecé Editores,
Buenos Aires, 1960, p. 142)
10
Introducción (III)
  • La relación de agregación es también bastante
    frecuente. Por ejemplo, cuando decimos que
  • Una empresa se compone de una serie de
    departamentos
  • El catálogo comercial se compone de una serie de
    productos
  • La carta de un restaurante se compone de una
    serie de platos y bebidas
  • Tipos
  • Composición. La parte (departamento) desaparece
    cuando desaparece el todo (Empresa). Otro
    ejemplo casa/cocina.
  • Contenedor. El componente (Ratón) no desaparece
    con el contenedor (Computadora). Otro ejemplo
    cesta/manzanas.

Catálogo
Producto
Empresa
Departamento
11
Herencia
  • La relación en la que una clase base es el
    supertipo o generalización de una subclase o
    subtipo (como la clase base Persona y la subclase
    Librero). Entender los mecanismos de la herencia
    implica comprender el polimorfismo

12
Un primer ejemplo de herencia
  • Empezamos representando la relación de herencia
    entre vehículo y autobus, para una agencia de
    alquiler

public class Vehiculo public int precioDia
36 public String marcaModelo "Volvo"
public Vehiculo() System.out.println(
"Construyo un vehículo") public void
mostrarCaracteristicas() System.out.print(
"Marca " marcaModelo Precio "
precioDia)
public class Autobus extends Vehiculo public
int plazas 55 public Autobus()
System.out.println( "Ha creado un autobus" )
public void mostrarCaracteristicas()
System.out.print( "Marca " marcaModelo
Precio " precioDia) System.out.println( "
Plazas " plazas )
public static void main(String args)
Autobus v1 new Autobus()
v1.mostrarCaracteristicas()
Construyo un vehículo Ha creado un autobus Marca
Volvo Precio 36 Plazas 55
  • Es un primer ejemplo en el que el objeto v1
    (clase Autobus) hereda los atributos de la
    clase Vehículo (usa la palabra extends)
  • marcaModelo
  • precioDia

13
Algunas críticas
  • El ejemplo anterior mostraba la herencia de
    atributos, pero tenía varios inconvenientes,
    entre los que destaca
  • No aprovecha la herencia de métodos
  • Los atributos no son parametrizados (sólo hay
    Volvos?)
  • Repetimos la sentencia System.out.print( "Marca
    " marcaModelo "Precio " precioDia) en la
    clase hija
  • Los datos no son protegidos o encapsulados
    (principio de ocultamiento de información)
  • En resumen, podemos hacerlo mejor

14
Mejorando el ejemplo
public class Vehiculo protected int
precioDia protected String marcaModelo
public Vehiculo( String marcaModelo, int
precioDia ) defMarcaModelo( marcaModelo
) defPrecioDia( precioDia )
System.out.println( "Construyo un vehículo")
public void mostrarCaracteristicas()
System.out.print( "Marca " marcaModelo
Precio " precioDia) public void
defPrecioDia( int precioDia )
this.precioDia precioDia ...
public class Autobus extends Vehiculo private
int plazas 55 public Autobus( String
marcaModelo, int precioDia, int plazas)
super( marcaModelo, precioDia ) this.plazas
plazas System.out.println( "Ha creado un
autobus" ) public Autobus( String
marcaModelo, int precioDia ) super(
marcaModelo, precioDia ) System.out.println(
"Ha creado un autobus" ) void
mostrarCaracteristicas() super.mostrarCaract
eristicas() System.out.println( " Plazas "
plazas )
DESDE MAIN() Autobus v1 new Autobus( "Volvo
550", 120, 57) v1.mostrarCaracteristicas() v1.de
fPrecioDia( 130 ) v1.mostrarCaracteristicas()
Construyo un vehículo Ha creado un autobus Marca
Volvo 550 Precio 120 Plazas 57 Marca Volvo 550
Precio 130 Plazas 57
15
Notas al ejemplo
  • En Vehiculo
  • Los atributos son protected esto significa que
    serán privados para las clases hijas
  • En Autobus
  • Usamos extends para indicar que es una clase hija
    de Vehiculo
  • El atributo plazas tiene un valor por defecto de
    55, que sería el que tomase con el segundo
    constructor. Observar que el segundo constructor
    no recibe valor para esta variable, por tanto, su
    valor sería el de la inicialización (el 55)
  • El uso de super() nos permite enviar valores al
    constructor de la clase madre
  • El método mostrarCaracteristicas() sobreescribe o
    anula el método idéntico de la clase madre. Para
    acceder al método anulado usa super.
  • super.mostrarCaracteristicas()
  • De esta forma el interprete Java sabe que
    queremos ejecutar la versión de
    mostrarCaracteristicas() que está en la clase
    madre
  • En main
  • Observar la herencia de métodos el objeto de la
    clase Autobus llama a defPrecioDia(), método
    heredado de la clase Vehiculo

16
Los usos de la palabra super
  • En la forma de llamada a una función significa
    una llamada al constructor de la clase madre.
    Debe colocarse en la primera línea del
    constructor de la hija
  • Autobus( String marcaModelo, int precioDia, int
    plazas)
  • super( marcaModelo, precioDia )
  • this.plazas plazas
  • System.out.println( "Ha creado un autobus" )
  • En la forma de referencia a un objeto (super.)
    significa que llamamos a un método de la clase
    madre que ha sido sobreescrito
  • void mostrarCaracteristicas()
  • super.mostrarCaracteristicas()
  • System.out.println( " Plazas " plazas )

17
Modificadores de acceso y herencia
18
Herencia de datos privados (private)
  • Si algo es private en la clase madre NO SE PUEDE
    ACCEDER DESDE LA SUBCLASE (NO SE HEREDA). Pero si
    se puede acceder desde la subclase a un método de
    la clase madre que usa ese dato. Por ejemplo, si
    hago que el precio sea privado
  • public class Vehiculo   private int
    precioDia    ....
  • Entonces puedo mostrar por pantalla el precio
    PORQUE LO MUESTRA UN METODO HEREDADO DE LA
    SUPERCLASE, getPrecioDia()
  • public class j08_agencia_alquiler   public
    static void main(String args)     Autobus v
    new Autobus( "XXX 800", 140, 58)   
    System.out.println( v.getPrecioDia() )
  •  
  • v.getPrecioDia() es un método heredado de la
    clase madre y es este método el responsable de
    mostrar el precio por pantalla. Pero desde la
    clase Autobus (subclase) no puedo usar precioDia,
    tampoco desde la clase j08_agencia_alquiler, que
    esta en el mismo paquete 

19
Herencia de datos protected (protegidos)
  • Si algo es protected en la clase base SE PUEDE
    ACCEDER DESDE LA SUBCLASE Y LAS CLASES DEL MISMO
    PAQUETE (aunque no sean subclases). Ejemplo
    siguiendo lo anterior si ponemos
  • public class Vehiculo   protected int
    precioDia    ....
  • Las siguientes líneas en main() serían correctas
  • public class j08_agencia_alquiler   public
    static void main(String args)     Autobus v
    new Autobus( "XXX 800", 140, 58)   
    System.out.println( v.getPrecioDia() )   
    System.out.println( v.precioDia
    )                    // NO ES UN ERROR
  •  
  • Puede observarse que el atributo precioDia es
    accesible para la clase j08_agencia_alquiler
    (donde está main()), PORQUE ESTA EN EL MISMO
    PAQUETE.

20
Herencia de datos public (públicos)
  • Accesible para cualquier subclase o clase (dentro
    o fuera del paquete).
  •  
  • POR DEFECTO Si no pongo modificador, los
    atributos y métodos son
  • Públicos para las clases del mismo paquete o
    subclases
  • Privados para las clases de otros paquetes o
    subclases

21
Herencia de datos un consejo
  • A modo de resumen y consejo general
  • Si queremos que algo se herede y se pueda usar
    desde otro paquete, usar public
  • Si queremos que algo se herede y no se pueda usar
    desde otro paquete (pero si desde el propio
    paquete), usar protected
  • Si no se quiere heredar ni acceder, private.

22
Otro ejemplo de sobreescritura de métodos
  • Las clases hijas (Rectangulo y Circulo)
    sobreescriben el método getArea()

public class Figura protected Punto
posicion public void setPosicion(Punto
posicion) this.posicion posicion
public Punto getPosicion() return
posicion public double getArea() return
0
public class Circulo extends Figura private
double radio static final public double PI
3.1416 public double getArea()
return radio radio PI
public class Rectangulo extends Figura
private double ancho private double largo
public double getArea() return
ancho largo
Cada subtipo de figura tiene un método
getArea(), pero cada método implementa a su
manera el cálculo del área. Por ello se dice que
nos encontramos ante polimorfismo un interfaz y
múltiples implementaciones. Un interfaz ya que el
interfaz (la declaración del método) es
idéntico. Múltiples implementaciones hay
múltiples formas de calcular el área.
23
Polimorfismo
  • La sobreescritura de métodos permite el
    polimorfismo. La clase madre especifica un
    método, que las clases derivadas sobreescriben,
    de tal forma que cada clase derivada tiene su
    implementación del método
  • Por ello, se habla de polimorfismo un interfaz
    (la misma declaración de método) y múltiples
    implementaciones (múltiples formas de calcular el
    área)
  • Veamos el siguiente ejemplo. Tenemos una
    referencia (f) de la clase madre Figura cómo
    sabe el programa el método getArea() que debe
    ejecutar?, en función del objeto que se crea (en
    este caso un círculo)
  • public static void main(String args)
  • Figura f
  • f new Circulo( 40, 40, 3 )
  • System.out.println( f.getArea() )
  • f new Rectangulo( 12, 10, new Punto(30, 33)
    )
  • System.out.println( f.getArea() )

24
Clases abstractas
  • En nuestro ejemplo de figuras la clase madre no
    tiene implementación del método getArea()
  • Esto no es raro en una clase madre, en muchas
    ocasiones las clases más elevadas en una
    jerarquía de herencia especifican un interfaz
    (declaración de función), sin definir una
    implementación. En nuestro ejemplo no se puede
    calcular el área de una figura (si de un
    Rectángulo o un Círculo)
  • Denominamos clases abstractas a aquellas que
    tienen o heredan un método abstracto, es decir,
    métodos declarados pero no implementados.
  • No puede haber instancias de las clases
    abstractas, lo que no resulta extraño nos puede
    interesar que se hagan instancias de Rectangulo o
    Circulo, pero no permitir instancias de Figura.
  • En nuestro ejemplo la clase madre puede ser
  • package figuras.dominio
  • abstract public class Figura
  • protected Punto posicion
  • public void setPosicion(Punto posicion)
  • this.posicion posicion
  • public Punto getPosicion()
  • return posicion
  • abstract public double getArea()

Las clases hijas deben implementar el método
abstracto
25
final
  • La palabra final tiene varios sentidos
  • Precediendo a una variable la define como una
    constante y no puede ser modificada
  • Precediendo a un método indica que el método no
    puede ser sobrescrito
  • Precediendo a una clase indica que no se pueden
    definir subclases

26
Agregación
  • Una relación en la que el objeto es una parte de
    otro objeto (como la batería es una parte del
    teléfono móvil). Nos ayudaremos de la clase
    Vector del JDK

27
Agregación composición
  • En ocasiones interesa crear objetos que se
    componen de otros objetos
  • La parte desaparece cuando desaparece el todo

public class Casa private Dormitorio
dormitorios private Salon salon private
Cocina cocina
28
Agregación contenedor
  • El componente (por ejemplo, un producto de un
    catálogo comercial) no desaparece con el
    contenedor (catálogo)
  • Conviene usar alguna de las clases del JDK para
    hacer colecciones de objetos, por ejemplo Vector,
    ArrayList, etc.
  • Están en el paquete java.util

29
Vector (I)
  • En Java las matrices son de longitud fija, una
    vez creadas no se puede modificar su tamaño
  • Hay un truco para saltarse esta limitación crear
    otra matriz más grande y copiar de la matriz
    original a la nueva
  • Java nos suministra una clase, denominada Vector,
    que nos permite utilizar una matriz de longitud
    variable
  • Constructores
  • Vector() tamaño inicial de 100 y se incrementa
    duplicando tamaño
  • Vector( int tamaño ) señala el tamaño y se
    incrementa duplicando tamaño
  • Vector( int tamaño, int incremento ) señala
    tamaño e incremento
  • Para añadir add( Object elemento ). Ejemplo
  • Vector v new Vector(50,5)
  • v.add( new Persona( Pedro ) )
  • En muchos métodos se tiene en cuenta el índice o
    posición dentro del Vector. Por ello, conviene
    recordar que el primer elemento es el cero. Para
    insertar en una posición determinada (desplazando
    el resto hacia la derecha) insertElementAt(
    Object elemento, int posición )

30
Vector (II)
  • Para conocer el número de elementos, así como la
    capacidad del Vector tenemos int size() e int
    capacity()
  • Vector v new Vector(50,5)
  • v.addElement( new Persona( Pedro ) )
  • System.out.println( v.size() ) // Muestra 1
  • System.out.println( v.capacity() ) // Muestra
    50
  • Para eliminar un elemento removeElementAt( int
    posición ). Desplaza los elementos de la derecha
    para llenar el hueco.
  • Para obtener el elemento de la posición indicada
    Object elementAt( int posición ) u Object get(
    int posición )

31
Versión final del proyecto de las figuras
  • Vamos a ver como queda finalmente el proyecto de
    las figuras, en el que se ha aplicado
  • Modularización se ha separado en tres paquetes
    la presentación, clases del dominio y la clase de
    inicio
  • Encapsulamiento datos privados. Tambien la
    complejidad de la presentación queda encapsulada
    (oculta), al final no hay más que llamar al
    método VistaFiguras.mostrar(), pasando como
    argumento el objeto que se quiere mostrar
  • Sobrecarga de métodos
  • Herencia hay una clase madre Figura que tiene
    métodos y atributo para la posición de la figura
  • Clase abstracta la clase Figura es además
    abstracta, ya que tiene el método abstracto
    getArea()
  • Agregación la clase Pagina es un contenedor de
    figuras
  • Una clase (Figura) usa de otra (Punto). El
    atributo Punto posicion de la clase Figura hace
    referencia al punto de su posición
  • Atributo static y final Circulo.PI, ya que
    sólo hay un número PI, aunque haya cero o
    millones de círculos
  • Métodos static VistaFigura.mostrar(), no hace
    falta instanciar la clase para llamar al método.
    Es una forma de implementación común en clases de
    utilidad.

32
Versión final del proyecto de las figuras. Los
puntos y las figuras
  • package figuras.dominio
  • public class Punto
  • private int x
  • private int y
  • public Punto(int x, int y)
  • setPunto(x, y)
  • public Punto(Punto p)
  • setPunto(p )
  • public void setPunto(int x, int y)
  • this.x x
  • this.y y
  • public void setPunto(Punto p)
  • x p.getX()
  • y p.getY()

Todas las figuras usan de Punto, ya que todas
heredan el atributo 'posicion' de Figura Figura
es una clase abstracta
package figuras.dominio abstract public class
Figura protected Punto posicion
public void setPosicion(Punto posicion)
this.posicion posicion public Punto
getPosicion() return posicion
abstract public double getArea()
33
Versión final del proyecto de las figuras. Los
círculos
  • package figuras.dominio
  • public class Circulo extends Figura
  • private double radio
  • static final public double PI 3.1416
  • public Circulo()
  • public Circulo( double nuevoRadio, Punto
    nuevaPosicion )
  • setRadio( nuevoRadio )
  • setPosicion( nuevaPosicion )
  • public Circulo( double nuevoRadio, int
    posicionX, int posicionY )
  • setRadio( nuevoRadio )
  • posicion new Punto( posicionX,
    posicionY )
  • public Circulo( Circulo circulo )
  • setRadio( circulo.getRadio() )
  • setPosicion( circulo.getPosicion())

Los círculos heredan de Figura, por tanto tienen
que implementar el método getArea()
34
Versión final del proyecto de las figuras. Los
rectángulos
  • package figuras.dominio
  • public class Rectangulo extends Figura
  • private double ancho
  • private double largo
  • public Rectangulo( double ancho, double
    largo, Punto posicion )
  • setDimensiones( ancho, largo )
  • setPosicion(posicion)
  • public void setDimensiones( double ancho,
    double largo )
  • this.ancho ancho
  • this.largo largo
  • public double getArea()
  • return ancho largo
  • public String toString()

35
Versión final del proyecto de las figuras. La
página (agregador)
  • package figuras.dominio
  • import java.util.
  • public class Pagina
  • private Vector vecFiguras new Vector()
  • public void agregar( Figura fig )
  • vecFiguras.add( fig )
  • public boolean desagregar( int indice )
  • if ( indice lt vecFiguras.size() )
  • try
  • vecFiguras.remove(indice)
  • return true
  • catch (Exception e) return false
  • return false
  • Utilizamos la clase java.util.Vector para agregar
    figuras
  • La utilidad de usar la herencia (o los interface
    lógicos) en agregar() usamos una referencia
    genérica (Figura fig). Este método puede recibir
    cualquier clase hija (Rectangulo, Circulo, etc.).
    Es muy interesante ya que, si no fuese así,
    tendríamos que implementar el método agregar para
    cada una de las subclases
  • En obtener() no eliminamos o quitamos el objeto
    del vector, simplemente devolvemos una referencia
    al objeto. Por qué necesitamos hacer casting?
  • Gestionamos excepciones con try - catch

36
Versión final del proyecto de las figuras. La
visualización
  • package figuras.presentacion
  • import figuras.dominio.
  • public class VistaFiguras
  • public static void mostrar( Circulo cir )
  • if ( cir ! null )
  • System.out.println( cir.toString() )
  • else
  • System.out.println( "Error al
    intentar mostrar el círculo" )
  • public static void mostrar( Rectangulo rec )
  • if ( rec ! null )
  • System.out.println( rec.toString() )
  • else
  • System.out.println( "Error al
    intentar mostrar el rectángulo" )
  • Aspectos a resaltar
  • Polimorfismo con sobrecarga de métodos todos los
    métodos se llaman igual, pero actúan de forma
    diferente (patrón estrategia)
  • Para mostrar las figuras de una página
    recorremos los elementos con un for(). Dentro del
    for(), para obtener la figura (sea un rectángulo
    o un círculo) usamos una referencia genérica del
    tipo Figura (clase madre), a la que mandamos el
    mensaje toString(). Un ejemplo típico de
    polimorfismo usamos el mismo mensaje (toString)
    para producir comportamiento diferente, en
    función del objeto unos se representan de una
    forma y otros de otra

37
Versión final del proyecto de las figuras. El
inicio
  • import figuras.presentacion.
  • class Inicio
  • //// Usa agregador
  • public static void main(String args)
  • Circulo primero new Circulo( 23, 2, 3
    )
  • Circulo copia new Circulo( primero )
  • Circulo tercero new Circulo( 17, new
    Punto(8,9) )
  • Rectangulo rectangulo new
    Rectangulo(3.5, 2, new Punto(55,54))
  • Pagina pag new Pagina()
  • pag.agregar( primero)
  • pag.agregar( copia)
  • pag.agregar( tercero )
  • pag.agregar( rectangulo )
  • VistaFiguras.mostrar( pag )

Puesto que el método mostrar() es static podemos
usar VistaFiguras sin instanciarla
Write a Comment
User Comments (0)
About PowerShow.com