3. Interfaces
             Herencia y clases abstractas
                   Object y herencia simple
                   Clases abstractas y métodos genéricos
             Fundamento / El por qué
             ¿Qué son? Definición
             Implementación, simple y múltiple
             Herencia de Interfaces


Programación III                        Tema 3 - Interfaces
Herencia - Definición
   • Relación es-un entre dos clases: coche  vehículo,
     alumnopersona, rectángulopolígono, etc.
   • Clase hija (subclase)  clase padre (superclase)
           – Hijas - más concretas, padres - comportamiento más general
   • En Java, cada hija sólo tiene un padre: herencia simple,
     aunque puede tener N hijas
   • La raíz de la jerarquía de clases en Java es la clase Object
   • Una clases hereda (tiene) todos los métodos y atributos de
     sus clases superiores (de la clase hasta Object)
   • Sólo puede acceder directamente a los que no sean privados
     (private)
   • Ventajas principales:
           – reutilización de código
           – diferenciación de código          (menos “if”s)
Programación III                        Tema 3 - Interfaces
Sintaxis
   • La relación jerárquica se representa mediante extends
                    class <hija> extends <padre>
   • Ejemplo:               Figura


                          Rectángulo

                   class Rectangulo extends Figura {
                          ...
                   }
   • La herencia es transitiva: si A  B y B  C, A  C
   • Si no hay cláusula extends, la clase deriva de Object




Programación III                     Tema 3 - Interfaces
Ejemplo de herencia
   class Persona{
                                                    class Alumno extends Persona {
      private int edad;
                                                       private int curso;
      private String nombre;
                                                       private char grupo;
                                                       private String titulacion;
         Persona (int e, String n){
              edad = e;
                                                           Alumno (int c, char g, String t){
              nombre = n;
                                                                curso = c;
         }
                                                                grupo = g;
         /* Métodos set/get para todos los
         atributos */                                           titulacion = t;
   }                                                       }
                                                           /* Métodos set/get para todos los
                                                           atributos */
                   Persona                          }


                                                    • Este código da un error ¿por qué?
                   Alumno




Programación III                         Tema 3 - Interfaces
Llamada de constructores
                      en herencia 1 - super
   • Cuando en una clase no se define ningún
     constructor, Java crea (aunque no se ve) el
     constructor por defecto
   class Persona{
      private int edad;
      private String nombre;

         Persona ( ){ //Constructor por defecto. Existe, pero no se ve.
         }
         /* Métodos set/get para todos los atributos */
         ...
         public static void main(String args[]){
              //Se puede comprobar que existe, creando objetos Persona
              Persona p1 = new Persona();
              /* La llamada al constructor vacío no da error, porque Java
         lo ha        creado */
         }
   }
Programación III                     Tema 3 - Interfaces
Llamada de constructores
                     en herencia 2 - super
   • En el momento en el que el programador crea otro
     constructor, el constructor por defecto deja de existir.
   class Persona{
      private int edad;
      private String nombre;

         Persona (int e, String n){
              edad = e;
              nombre = n;
         }
         /* Métodos set/get para todos los atributos */
         ...
         public static void main(String args[]){
              /* Esta misma llamada daría error, porque no existe un constructor
         con esas características */
              Persona p1 = new Persona();
              /*Sí es posible llamar al constructor definido */
              Persona p2 = new Persona(20, “Ana”);
         }
   }
Programación III                         Tema 3 - Interfaces
Llamada de constructores
                     en herencia 3 - super
   • Cuando una clase tiene una
     clase padre, lo primero que                    class Alumno extends Persona {

     hace su constructor (aunque no                     private int curso;
                                                        private char grupo;
     lo veamos), es llamar al                           private String titulacion;
     constructor de la clase
                                                           Alumno(int c, char   g, String t){
     padre (al constructor vacío:                                /*Llamada al   constructor de la
     super( );)                                                  clase padre,   existe pero no se
                                                                 ve*/
                                                                 super();
   class Persona{                                                curso = c;
      private int edad;                                          grupo = g;
      private String nombre;                                     titulacion =   t;
                                                           }
                                                    }
         Persona (int e, String n){
              edad = e;
              nombre = n;                           • Este constructor produce un error
         }                                            ¿por qué?
         /* Métodos set/get para todos los
         atributos */
         ...
   }
Programación III                         Tema 3 - Interfaces
Llamada de constructores
                     en herencia 4 - super
  • Solución 1. Crear constructor vacío              • Solución 2. Llamar explícitamente al
                                                       constructor del padre que sí existe
  class Persona{                                     class Persona{
      private int edad;                                  private int edad;
      private String nombre;                             private String nombre;

        Persona ( ) { }                                    Persona (int e, String n){
        Persona (int e, String n){                               edad = e;
              edad = e;                                          nombre = n;
              nombre = n;                                  }
        }                                            }
  }                                                  class Alumno extends Persona {
  class Alumno extends Persona {                         private int curso;
      private int curso;                                 private char grupo;
      private char grupo;                                private String titulacion;
      private String titulacion;
                                                           Alumno(int c, char g, String t,
        Alumno(int c, char g, String t){                          int e, String n){
              super();                                           super(e, n);
              curso = c;                                         curso = c;
              grupo = g;                                         grupo = g;
              titulacion = t;                                    titulacion = t;
        }                                                  }
  }                                                  }


Programación III                           Tema 3 - Interfaces
Ejemplo de llamada a
                         constructores
  class Figura {                                       class X {
     Figura (){                                           public static void main (...){
        s.o.p.(“Creando figura”);                            Cuadrado c1 = new
     }                                                    Cuadrado();
  }                                                       }
                                                       }
  class Rectangulo extends Figura
     {                                                 • ¿Qué sale por pantalla?
     Rectangulo (){                                    • ¿A qué se debe?
        s.o.p.(“Creando                                • (super)
     rectangulo”);
     }
  }

   class Cuadrado extends
         Rectangulo {
         Cuadrado (){
                 s.o.p.(“Creando cuadrado”);
         }
   }
Programación III                           Tema 3 - Interfaces
this
   • Dentro de un método, hace referencia al objeto
     que lo llama
   class Persona{
      private int edad;
      private String nombre;

     Persona (int edad, String nombre){
         edad = edad;
         nombre = nombre;
     }
   • ¿Qué pasa en este constructor? ¿Cómo resolverlo?
     void imprimirDatos(){
         s.o.p.(“Persona: “ + this.nombre + “ “ + this.edad);
         /* En este caso no sería necesario, es suficiente el
     nombre de los atributos */
     }
   }
Programación III                 Tema 3 - Interfaces
this y super
                                       class Alumno extends Persona{
   class Persona{                          private int curso;
      private int edad;                    private char grupo;
      private String nombre;               private String titulacion;

                                           Alumno(int c, char g, String t, int e, String n){
         Persona (int edad, String                super(e, n);
         nombre){                                 curso = c;
              this.edad = edad;                   grupo = g;
               this.nombre = nombre;              titulacion = t;
                                           }
                                           void imprimirDatos (){
         }                                        s.o.p.(curso + “-” + grupo);
         void imprimirDatos(){                    s.o.p.(“(“ + titulacion + “)”);
              s.o.p.(“Persona: “);         }
                                           void imprimirTodos(){
              s.o.p.(nombre + “ “);
                                                  super.imprimirDatos();
              s.o.p.(edad);                       this.imprimirDatos();
         }                                        imprimirDatos();
   }                                       }
                                           public static void main(String args[]){
                                             Alumno al;
                                             al = new Alumno(1, 'a', "ITTET", 18, "Pedro");
                                             al.imprimirTodos();
                                           }
                                       }
                                       •   ¿Qué obtenemos por pantalla?

Programación III                           Tema 3 - Interfaces
this en constructores
   class Alumno extends Persona{
      ...

         Alumno(int c, char g, String t, int e,
         String n){
              super(e, n);
              curso = c;
              grupo = g;
              titulacion = t;
         }

         Alumno(int c, char g, String t){
              this(c, g, t, 0, “Sin definir”);
         }

         ...
   }




Programación III                         Tema 3 - Interfaces
Resumen this y super

       – this
               • Es la referencia al propio objeto sobre el que se está trabajando.
               • No hace falta usarla para acceder a los atributos y métodos propios.
               • Pero a veces es necesaria cuando se quiere pasar la referencia al
                 propio objeto como parámetro de otro método.
               • En constructores puede usarse para llamar entre ellos (lo primero)
       – super
               • Permite referenciar a la clase padre.
               • Se emplea cuando se ha redefinido un método y se quiere acceder al
                 método del padre (si no se usara esta palabra reservada se llamaría
                 al método de la propia clase y no habría forma de invocar el del
                 padre). [super.método(...)]
               • Permite también llamar al constructor de la clase padre desde el
                 constructor de la clase hija. [super(...)] Esto es lo primero que se
                 hace en todo constructor (si no se indica explícitamente, se hace sin
                 parámetros).


Programación III                           Tema 3 - Interfaces
Comprob. tipo en ejecución

   • instanceof
           – Permite controlar la clase a la que
             pertenece un objeto (no la variable, el
             objeto)

                    Vehiculo[] v = new Vehiculo[3]
                    v[0] = new Coche();
                    v[1] = new Moto();
                    v[2] = new CocheJuguete();
                    ...
                    if (v[i] instanceof Moto) {
                        (Moto)v[i] ... }
Programación III                  Tema 3 - Interfaces
Método abstracto
   • Precedido de la palabra clave abstract
   • Un método abstracto es el que no tiene
     implementación
           class X {
             abstract void m1();
           }
   • NO es lo mismo que un método “vacío”
           class X {
             void m1(){ }
           }
   • Una clase que contiene un método abstracto, es
     una clase abstracta, y debe de llevar el modificador
     abstract
           abstract class X {
             abstract void m1();
           }
Programación III                   Tema 3 - Interfaces
Herencia de métodos
                              abstractos
   • Cuando una clase hereda un método abstracto, tiene dos
     opciones:
           – Implementar el método (darle código)
                   class Y extends X {
                     void m1(){...}
                   }
           – No implementarlo (no hacer nada con él). En este caso la clase pasa
             a ser abstracta (si no se pone abstract no compila)
                   abstract class Y extends X {
                   }

   • Una clase es abstracta si:
           – Tiene un método abstracto definido dentro (clase X)
           – Hereda un método abstracto y no lo implementa (clase Y, ejem 2)
   • NO se pueden crear objetos de una clase abstracta:
                   X x1; //Correcto
                   x1 = new X(); //Incorrecto
                   ¿Por qué?

Programación III                                Tema 3 - Interfaces
Utilidad de métodos
                                  abstractos
   • Si no se pueden crear objetos de clases abstractas ¿para qué sirven?
   • Son clases de definición
           – Indican cómo deben comportarse las subclases, qué métodos deben tener
             obligatoriamente (porque la herencia no puede quitar métodos)
           – Sirven para proporcionar un comportamiento y definición general a las
             subclases, permitiendo especificar en cada subclase una implementación diferente
                   • No compromete cuál debe ser ese comportamiento
           – Puede haber algunos métodos no abstractos porque su código sí pueda definirse
                   • ej.: FiguraGeometrica – void dibujar() { dibujarArea(); dibujarAristas() }


                                                abstract Animal
                                  abstract void emitirSonido( );


       Perro                               Felino                                 Ave
       void emitirSonido( ){               void emitirSonido( ){                  void emitirSonido( ){
          s.o.p.(“Guau”);                     s.o.p.(“Grrr...”);                     s.o.p.(“Pio-pio”);
       }                                   }                                      }


                                          Gato         Lince          Pantera       Canario       Golondrina

Programación III                                         Tema 3 - Interfaces
Modificador final

       • final
               – Indica que la definición de la clase está completa.
                   • No se puede heredar de esa clase (no puede tener
                     subclases).
                   • Si una clase es declarada abstract y final  Error de
                     compilación
               – Otros usos de final :
                   • en atributos indica constantes (su valor no puede cambiar)
                   • en métodos indica que no se pueden redefinir en subclases
                     (una clase final hace a todos sus métodos finales)




Programación III                          Tema 3 - Interfaces
Interfaces: fundamento

   • Ejemplo: bubble sort
           – Ordenar fechas
           – Ordenar fracciones
           – ¿Cómo generalizamos?




Programación III              Tema 3 - Interfaces
Ordenación de fechas
           public class OrdenarFechas {
             static void ordenaArray( Fecha v[] )
             // Ordena array de fechas por bubble sort
             {
               for (int i=0; i<v.length-1; i++) {
                     for (int j=1; j<v.length-i; j++) {
                           if (v[j-1].esMayorQue(v[j])) {
                                 Fecha temp = v[j];
                                 v[j] = v[j-1]; v[j-1] = temp;
                           }
                     }
               }
             }
           ...

Programación III                 Tema 3 - Interfaces
Ordenación de fracciones
           public class OrdenarFracciones {
             static void ordenaArray( Fraccion v[] )
             // Ordena array de fracciones por bubble sort
             {
               for (int i=0; i<v.length-1; i++) {
                     for (int j=1; j<v.length-i; j++) {
                           if (v[j-1].esMayorQue(v[j])) {
                                 Fraccion temp = v[j];
                                 v[j] = v[j-1]; v[j-1] = temp;
                           }
                     }
               }
             }
           ...

Programación III                 Tema 3 - Interfaces
¿Cómo generalizar?
   • Método de ordenación idéntico
           – Son clases distintas
           – Ambas se pueden comparar por mayor
           – Pero no se pueden heredar (no tienen nada que ver)
   • ¿Cómo lo generalizamos?
           public class OrdenarLoQueSea {
             static void ordenaArray( LoQueSea v[] ) {
              for (int i=0; i<v.length-1; i++) {
                     for (int j=1; j<v.length-i; j++) {
                            if (v[j-1].esMayorQue(v[j])) {
                                   LoQueSea temp = v[j];
                                   v[j] = v[j-1]; v[j-1] = temp;
                            }
                     }
              } ...

Programación III                   Tema 3 - Interfaces
Solución
                   interface Ordenable {
                     boolean esMayorQue( Ordenable o );
                   }
                   public class Ordenar {
                     static void ordenaArray( Ordenable v[] ) {
                           for (int i=0; i<v.length-1; i++) {
                                   for (int j=1; j<v.length-i; j++) {
                                          if (v[j-1].esMayorQue(v[j])) {
                                                  Ordenable temp = v[j];
                                                  v[j]=v[j-1]; v[j-1]=temp;
                     }     }       }      }
                   class Fraccion implements Ordenable {
                     public boolean esMayorQue( Ordenable o ) {
                           if (o instanceof Fraccion) {
                                   Fraccion f2 = (Fraccion) o;
                                   return (1.0*num/den > 1.0*f2.num/f2.den);
                           } else return false;
                     ...

Programación III                           Tema 3 - Interfaces
El por qué de los interfaces (1)
   • Herencia Múltiple
           – Una clase tiene más de un padre
           – Presenta problemas cuando:
                   • Se heredan varias implementaciones para un mismo método
                   • Se heredan varias copias de un mismo atributo
   • Ejemplo:
                                                               Vehiculo




                                    VehiculoTerrestre                         VehiculoAcuatico




                            Coche                       VehiculoAnfibio                          Barco


Programación III                                        Tema 3 - Interfaces
El por qué de los interfaces
                      (2)
   • Complejidad (Eiffel, C++):
           – Si la clase Vehículo tuviera un atributo llamado
             matrícula, ¿Cuántas matrículas tendría la clase
             VehiculoAnfibio?
           – ¿Si Vehículo tuviera un método implementado
             de forma diferente por VehiculoTerrestre y por
             VehiculoAcuatico?
   • Java no permite la herencia múltiple
           – ¿Cómo resuelve Java estas jerarquías?
           – Mediante otro mecanismo: los interfaces

Programación III                 Tema 3 - Interfaces
¿Qué es un interface?
   • Es un conjunto de métodos
           – Sólo cabeceras, sin implementación
           – Definen un comportamiento específico para un conjunto
             de objetos
   • Es una forma de crear tipos (como las clases)
           – Se pueden declarar variables
           – Se pueden declarar métodos
   • Y debido a esto:
           – Sus métodos son “abstractos”
           – No se pueden instanciar (como las clases abstractas)
           – No se hereda codificación, sólo definición

Programación III                    Tema 3 - Interfaces
Definición de interfaces
   • Palabra reservada interface seguida de una lista de
     métodos (cabeceras) sin implementación
   • Ejemplo 1:
                   interface UnInterface
                   {
                     void mensaje1();
                     void mensaje2();
                   }
   • Ejemplo 2:
                   interface Driveable
                   {
                     boolean startEngine();
                     void stopEngine();
                     float accelerate(float acc);
                     boolean turn(Direction dir);
                   }
   • Todos los métodos de un interface son públicos
Programación III                     Tema 3 - Interfaces
Implementación de interfaces (1)
   • Para “implementar” un interface:
           – Cláusula implements
           – Cuando se relaciona una clase con una interfaz y no se implementan los métodos, la
             clase pasa a ser “abstracta” (no se puede instanciar).
   • Ejemplo 1:
                     class UnaClase implements UnInterface
                     {
                        void mensaje1() { System.out.println(“1”); }
                        void mensaje2() { System.out.println(“2”); }
                     }
   • Ejemplo 2:
                     class Automobile implements Driveable
                     {
                        public boolean startEngine()
                        {
                           if (notTooCold) engineRunning = true; ...
                        }
                        public void stopEngine()
                        { ...
                           engineRunning = false;
                        }
                        public float accelerate(float acc)
                        { ...
                        }
                        public boolean turn(Direction dir)
                        { ...
                        }
                     }
Programación III                                Tema 3 - Interfaces
Implementación de interfaces (2)
   • En estos momentos:
           – La clase Automobile implementa el interface Driveable
           – La clase Automobile posee un tipo “extra”: El tipo Driveable
           – Todos los objetos de la clase Automobile pertenecen también al tipo Driveable
   • Un interface puede ser implementado por más de una clase
                     class Automobile implements Driveable
                     { ...
                     }
                     class LawnMower implements Driveable
                     { ...
                     }
           – En cualquier lugar donde se requiera un objeto del tipo Driveable podremos situar un
             objeto de la clase Automobile o de la clase LawnMower. De esta forma nos
             aseguramos que los métodos existen aunque no nos preocupa su implementación real.
             Estamos definiendo una API, una interfaz de programación que asegura un concepto,
             no una implementación concreta.
                     Automobile auto = new Automobile();
                     Lawnmower mower = new Lawnmower();
                     Driveable vehicle;
                     vehicle = auto;
                     vehicle.startEngine();
                     vehicle.stopEngine();
                     ...
                     vehicle = mower;
                     vehicle.startEngine();
                     vehicle.stopEngine();




Programación III                               Tema 3 - Interfaces
Interfaces - ejemplo

   • interfaz Comparable
           – Método int compareTo(Object o)
                   • Devuelve -1, 0, +1
   • Todas las clases que sean ordenables pueden
     implementar este interfaz
   • ¿Qué ventajas tiene el programador?
           – Regularidad: siempre se compara igual
           – Polimorfismo:
                   • void ordenaGrupo( Comparable c[] )


Programación III                          Tema 3 - Interfaces
Implem. de interfaces múltiples (1)
   • Una clase puede implementar más de un interface
     (herencia múltiple)
           – Ejemplo 1:
                    interface A
                    {
                      void mensaje1();
                      void mensaje2();
                    }
                    interface B
                    {
                      void mensaje3();
                      void mensaje4();
                    }
                    class C implements A, B
                    {
                      void mensaje1() {System.out.println(“1”);}
                      void mensaje2() {System.out.println(“2”);}
                      void mensaje3() {System.out.println(“3”);}
                      void mensaje4() {System.out.println(“4”);}
                    }


Programación III                        Tema 3 - Interfaces
Implem. de interfaces múltiples (2)
           – Ejemplo 2:
                   • Tenemos un nuevo interface: el interface Cloneable
                        interface Cloneable
                        {
                          Object clone();
                        }
                   • Tenemos una clase base para todos los tipos de vehículos llamada Vehicle
                   • Definamos Automobile:
                        class Automobile extends Vehicle                 implements Driveable, Cloneable
                        { ...
                          public boolean startEngine() {                 ... }
                          public void stopEngine() { ...                 }
                          public float accelerate( float                 acc ) { ... }
                          public boolean turn( Direction                 dir ) { ... }
                          public Object clone() { ... }
                        }
                   • Automobile debe implementar los métodos de todos los interfaces que
                     implemente si se quiere poder instanciar objetos de tipo Automobile.
                   • Los objetos de la clase Automobile pertenecerán a 4 tipos distintos
                     (se podrán usar como si fueran de cualquiera de esos tipos):
                        –   El tipo Automobile
                        –   El tipo Vehicle
                        –   El tipo Driveable
                        –   El tipo Cloneable

Programación III                                   Tema 3 - Interfaces
Herencia de interfaces
   •     Los interfaces pueden heredar mediante extends
                    interface A
                    {
                       void mensaje1();
                    }
                    interface B extends A
                    {
                       void mensaje2();
                    }
   •     Una clase que implemente el interface B deberá implementar los métodos de ambos
         interfaces si quiere poder crear objetos.
                    class C implements B
                    {
                       void mensaje1() {System.out.println(“1”);}
                       void mensaje2() {System.out.println(“2”);}
                    }
   •     Además, Java admite la herencia múltiple entre interfaces
                    interface A {
                       void mensaje1();
                    }
                    interface B extends A {
                       void mensaje2();
                    }
                    interface C extends A {
                       void mensaje3();
                    }
                    interface D extends B, C {
                       void mensaje4();
                    }
   •     La clase que implemente el interface D deberá implementar los 4 métodos si quiere que se
         puedan instanciar objetos.

Programación III                                    Tema 3 - Interfaces
Ejemplo: Interfaces y clases abstractas
                   interface ElementoVolador
                   {
                     void acelerar( int vel );
                   }
                   interface ElementoMecanicoVolador extends ElementoVolador
                   {
                     void arreglarMecanismos();
                   }
                   abstract class Avion implements ElementoMecanicoVolador
                   {
                     boolean elMotorFunciona;
                     public void arreglarMecanismos()
                     {
                           elMotorFunciona = true;
                     }
                   }
                   class AvionComercial extends Avion
                   {
                     int velocidad;
                     public void acelerar( int vel )
                     {
                           velocidad += vel;
                     }
                   }


Programación III                             Tema 3 - Interfaces
Ejercicios propuestos (1)
   • Implementación de Enumeration
                   • Queremos incorporar en la clase ListaEnlazada el interface de
                     java.util.Enumeration. Para ello:
                       – Definiremos una clase de paquete EnumeradorLista que implemente el
                         interface de Enumeration sobre una lista enlazada. Esto es, tiene que tener
                         un constructor que inicialice la secuencia, un método de comprobación de
                         final hasMoreElements() y un método de extracción del siguiente elemento
                         de la secuencia nextElement().
                       – Para evitar que esta clase la tenga que manipular directamente el usuario
                         incorporaremos a la clase ListaEnlazada un método enumeracion() que
                         devuelva una instancia de EnumeradorLista inicializada sobre la propia lista.
                       – Así, desde un programa podremos para recorrer cualquier lista y hacer algo
                         así como:
                            java.util.Enumeration e = l.enumeracion();
                            while (e.hasMoreElements())
                            {
                               System.out.print( " " + e.nextElement() );
                            }
                       – Esta clase EnumeradorLista es el clásico ejemplo de uso de clase interna.
                         Probar a definirla así.
                       – Cambiar la clase ListaEnlazada de acuerdo a todo esto. Probar en el main
                         que efectivamente la enumeración funciona.


Programación III                                   Tema 3 - Interfaces
Ejercicios propuestos (2)
   • Jerarquía de figuras
           – Crear una clase llamada Figura de la que extiendan las clases Cuadrado,
             Triángulo y Círculo. Figura debe ser una clase abstracta que contenga dos
             métodos void dibujar() y void borrar(). Por otro lado, cada clase
             descendiente de Figura va a redefinir estos métodos visualizando por
             pantalla, en cada caso, un mensaje.
                   • (Por ejemplo: “Dibujando cuadrado/triángulo/círculo”, “Borrando
                     cuadrado/triángulo/círculo”).
           – Crear por otro lado una clase Pizarra que tenga un atributo que sea un array
             de Figuras. Además, tendrá un método para añadir Figuras al array y otro
             para borrar todas las figuras del array.
                   • Para probar el funcionamiento, realizar una clase Ejemplo que añada varias
                     figuras (de cualquier tipo) a la pizarra. Ir viendo lo que saldría por pantalla para
                     ver cómo funciona el polimorfismo. También se puede llamar al método borrar
                     de la clase Pizarra para ver cómo se irían borrando todas las figuras.
           – Jerarquía de figuras + Interfaces
                   • Modificar el ejercicio anterior de la siguiente forma:
                        – Definir un interface llamado Coloreable que hace referencia a todos los objetos que
                          admiten un color, definiendo los métodos void cambiaColor( Color c ) que cambia el
                          color del objeto y el Color queColor() que devuelve el color del objeto.
                        – Hacer que Figura implemente el interfaz Coloreable, añadiendo los métodos y
                          atributos necesarios. ¿Dónde implementarías estos métodos? Hazlo.



Programación III                                      Tema 3 - Interfaces

Programación III (Java) - 03 Interfaces

  • 1.
    3. Interfaces Herencia y clases abstractas Object y herencia simple Clases abstractas y métodos genéricos Fundamento / El por qué ¿Qué son? Definición Implementación, simple y múltiple Herencia de Interfaces Programación III Tema 3 - Interfaces
  • 2.
    Herencia - Definición • Relación es-un entre dos clases: coche  vehículo, alumnopersona, rectángulopolígono, etc. • Clase hija (subclase)  clase padre (superclase) – Hijas - más concretas, padres - comportamiento más general • En Java, cada hija sólo tiene un padre: herencia simple, aunque puede tener N hijas • La raíz de la jerarquía de clases en Java es la clase Object • Una clases hereda (tiene) todos los métodos y atributos de sus clases superiores (de la clase hasta Object) • Sólo puede acceder directamente a los que no sean privados (private) • Ventajas principales: – reutilización de código – diferenciación de código (menos “if”s) Programación III Tema 3 - Interfaces
  • 3.
    Sintaxis • La relación jerárquica se representa mediante extends class <hija> extends <padre> • Ejemplo: Figura Rectángulo class Rectangulo extends Figura { ... } • La herencia es transitiva: si A  B y B  C, A  C • Si no hay cláusula extends, la clase deriva de Object Programación III Tema 3 - Interfaces
  • 4.
    Ejemplo de herencia class Persona{ class Alumno extends Persona { private int edad; private int curso; private String nombre; private char grupo; private String titulacion; Persona (int e, String n){ edad = e; Alumno (int c, char g, String t){ nombre = n; curso = c; } grupo = g; /* Métodos set/get para todos los atributos */ titulacion = t; } } /* Métodos set/get para todos los atributos */ Persona } • Este código da un error ¿por qué? Alumno Programación III Tema 3 - Interfaces
  • 5.
    Llamada de constructores en herencia 1 - super • Cuando en una clase no se define ningún constructor, Java crea (aunque no se ve) el constructor por defecto class Persona{ private int edad; private String nombre; Persona ( ){ //Constructor por defecto. Existe, pero no se ve. } /* Métodos set/get para todos los atributos */ ... public static void main(String args[]){ //Se puede comprobar que existe, creando objetos Persona Persona p1 = new Persona(); /* La llamada al constructor vacío no da error, porque Java lo ha creado */ } } Programación III Tema 3 - Interfaces
  • 6.
    Llamada de constructores en herencia 2 - super • En el momento en el que el programador crea otro constructor, el constructor por defecto deja de existir. class Persona{ private int edad; private String nombre; Persona (int e, String n){ edad = e; nombre = n; } /* Métodos set/get para todos los atributos */ ... public static void main(String args[]){ /* Esta misma llamada daría error, porque no existe un constructor con esas características */ Persona p1 = new Persona(); /*Sí es posible llamar al constructor definido */ Persona p2 = new Persona(20, “Ana”); } } Programación III Tema 3 - Interfaces
  • 7.
    Llamada de constructores en herencia 3 - super • Cuando una clase tiene una clase padre, lo primero que class Alumno extends Persona { hace su constructor (aunque no private int curso; private char grupo; lo veamos), es llamar al private String titulacion; constructor de la clase Alumno(int c, char g, String t){ padre (al constructor vacío: /*Llamada al constructor de la super( );) clase padre, existe pero no se ve*/ super(); class Persona{ curso = c; private int edad; grupo = g; private String nombre; titulacion = t; } } Persona (int e, String n){ edad = e; nombre = n; • Este constructor produce un error } ¿por qué? /* Métodos set/get para todos los atributos */ ... } Programación III Tema 3 - Interfaces
  • 8.
    Llamada de constructores en herencia 4 - super • Solución 1. Crear constructor vacío • Solución 2. Llamar explícitamente al constructor del padre que sí existe class Persona{ class Persona{ private int edad; private int edad; private String nombre; private String nombre; Persona ( ) { } Persona (int e, String n){ Persona (int e, String n){ edad = e; edad = e; nombre = n; nombre = n; } } } } class Alumno extends Persona { class Alumno extends Persona { private int curso; private int curso; private char grupo; private char grupo; private String titulacion; private String titulacion; Alumno(int c, char g, String t, Alumno(int c, char g, String t){ int e, String n){ super(); super(e, n); curso = c; curso = c; grupo = g; grupo = g; titulacion = t; titulacion = t; } } } } Programación III Tema 3 - Interfaces
  • 9.
    Ejemplo de llamadaa constructores class Figura { class X { Figura (){ public static void main (...){ s.o.p.(“Creando figura”); Cuadrado c1 = new } Cuadrado(); } } } class Rectangulo extends Figura { • ¿Qué sale por pantalla? Rectangulo (){ • ¿A qué se debe? s.o.p.(“Creando • (super) rectangulo”); } } class Cuadrado extends Rectangulo { Cuadrado (){ s.o.p.(“Creando cuadrado”); } } Programación III Tema 3 - Interfaces
  • 10.
    this • Dentro de un método, hace referencia al objeto que lo llama class Persona{ private int edad; private String nombre; Persona (int edad, String nombre){ edad = edad; nombre = nombre; } • ¿Qué pasa en este constructor? ¿Cómo resolverlo? void imprimirDatos(){ s.o.p.(“Persona: “ + this.nombre + “ “ + this.edad); /* En este caso no sería necesario, es suficiente el nombre de los atributos */ } } Programación III Tema 3 - Interfaces
  • 11.
    this y super class Alumno extends Persona{ class Persona{ private int curso; private int edad; private char grupo; private String nombre; private String titulacion; Alumno(int c, char g, String t, int e, String n){ Persona (int edad, String super(e, n); nombre){ curso = c; this.edad = edad; grupo = g; this.nombre = nombre; titulacion = t; } void imprimirDatos (){ } s.o.p.(curso + “-” + grupo); void imprimirDatos(){ s.o.p.(“(“ + titulacion + “)”); s.o.p.(“Persona: “); } void imprimirTodos(){ s.o.p.(nombre + “ “); super.imprimirDatos(); s.o.p.(edad); this.imprimirDatos(); } imprimirDatos(); } } public static void main(String args[]){ Alumno al; al = new Alumno(1, 'a', "ITTET", 18, "Pedro"); al.imprimirTodos(); } } • ¿Qué obtenemos por pantalla? Programación III Tema 3 - Interfaces
  • 12.
    this en constructores class Alumno extends Persona{ ... Alumno(int c, char g, String t, int e, String n){ super(e, n); curso = c; grupo = g; titulacion = t; } Alumno(int c, char g, String t){ this(c, g, t, 0, “Sin definir”); } ... } Programación III Tema 3 - Interfaces
  • 13.
    Resumen this ysuper – this • Es la referencia al propio objeto sobre el que se está trabajando. • No hace falta usarla para acceder a los atributos y métodos propios. • Pero a veces es necesaria cuando se quiere pasar la referencia al propio objeto como parámetro de otro método. • En constructores puede usarse para llamar entre ellos (lo primero) – super • Permite referenciar a la clase padre. • Se emplea cuando se ha redefinido un método y se quiere acceder al método del padre (si no se usara esta palabra reservada se llamaría al método de la propia clase y no habría forma de invocar el del padre). [super.método(...)] • Permite también llamar al constructor de la clase padre desde el constructor de la clase hija. [super(...)] Esto es lo primero que se hace en todo constructor (si no se indica explícitamente, se hace sin parámetros). Programación III Tema 3 - Interfaces
  • 14.
    Comprob. tipo enejecución • instanceof – Permite controlar la clase a la que pertenece un objeto (no la variable, el objeto) Vehiculo[] v = new Vehiculo[3] v[0] = new Coche(); v[1] = new Moto(); v[2] = new CocheJuguete(); ... if (v[i] instanceof Moto) { (Moto)v[i] ... } Programación III Tema 3 - Interfaces
  • 15.
    Método abstracto • Precedido de la palabra clave abstract • Un método abstracto es el que no tiene implementación class X { abstract void m1(); } • NO es lo mismo que un método “vacío” class X { void m1(){ } } • Una clase que contiene un método abstracto, es una clase abstracta, y debe de llevar el modificador abstract abstract class X { abstract void m1(); } Programación III Tema 3 - Interfaces
  • 16.
    Herencia de métodos abstractos • Cuando una clase hereda un método abstracto, tiene dos opciones: – Implementar el método (darle código) class Y extends X { void m1(){...} } – No implementarlo (no hacer nada con él). En este caso la clase pasa a ser abstracta (si no se pone abstract no compila) abstract class Y extends X { } • Una clase es abstracta si: – Tiene un método abstracto definido dentro (clase X) – Hereda un método abstracto y no lo implementa (clase Y, ejem 2) • NO se pueden crear objetos de una clase abstracta: X x1; //Correcto x1 = new X(); //Incorrecto ¿Por qué? Programación III Tema 3 - Interfaces
  • 17.
    Utilidad de métodos abstractos • Si no se pueden crear objetos de clases abstractas ¿para qué sirven? • Son clases de definición – Indican cómo deben comportarse las subclases, qué métodos deben tener obligatoriamente (porque la herencia no puede quitar métodos) – Sirven para proporcionar un comportamiento y definición general a las subclases, permitiendo especificar en cada subclase una implementación diferente • No compromete cuál debe ser ese comportamiento – Puede haber algunos métodos no abstractos porque su código sí pueda definirse • ej.: FiguraGeometrica – void dibujar() { dibujarArea(); dibujarAristas() } abstract Animal abstract void emitirSonido( ); Perro Felino Ave void emitirSonido( ){ void emitirSonido( ){ void emitirSonido( ){ s.o.p.(“Guau”); s.o.p.(“Grrr...”); s.o.p.(“Pio-pio”); } } } Gato Lince Pantera Canario Golondrina Programación III Tema 3 - Interfaces
  • 18.
    Modificador final • final – Indica que la definición de la clase está completa. • No se puede heredar de esa clase (no puede tener subclases). • Si una clase es declarada abstract y final  Error de compilación – Otros usos de final : • en atributos indica constantes (su valor no puede cambiar) • en métodos indica que no se pueden redefinir en subclases (una clase final hace a todos sus métodos finales) Programación III Tema 3 - Interfaces
  • 19.
    Interfaces: fundamento • Ejemplo: bubble sort – Ordenar fechas – Ordenar fracciones – ¿Cómo generalizamos? Programación III Tema 3 - Interfaces
  • 20.
    Ordenación de fechas public class OrdenarFechas { static void ordenaArray( Fecha v[] ) // Ordena array de fechas por bubble sort { for (int i=0; i<v.length-1; i++) { for (int j=1; j<v.length-i; j++) { if (v[j-1].esMayorQue(v[j])) { Fecha temp = v[j]; v[j] = v[j-1]; v[j-1] = temp; } } } } ... Programación III Tema 3 - Interfaces
  • 21.
    Ordenación de fracciones public class OrdenarFracciones { static void ordenaArray( Fraccion v[] ) // Ordena array de fracciones por bubble sort { for (int i=0; i<v.length-1; i++) { for (int j=1; j<v.length-i; j++) { if (v[j-1].esMayorQue(v[j])) { Fraccion temp = v[j]; v[j] = v[j-1]; v[j-1] = temp; } } } } ... Programación III Tema 3 - Interfaces
  • 22.
    ¿Cómo generalizar? • Método de ordenación idéntico – Son clases distintas – Ambas se pueden comparar por mayor – Pero no se pueden heredar (no tienen nada que ver) • ¿Cómo lo generalizamos? public class OrdenarLoQueSea { static void ordenaArray( LoQueSea v[] ) { for (int i=0; i<v.length-1; i++) { for (int j=1; j<v.length-i; j++) { if (v[j-1].esMayorQue(v[j])) { LoQueSea temp = v[j]; v[j] = v[j-1]; v[j-1] = temp; } } } ... Programación III Tema 3 - Interfaces
  • 23.
    Solución interface Ordenable { boolean esMayorQue( Ordenable o ); } public class Ordenar { static void ordenaArray( Ordenable v[] ) { for (int i=0; i<v.length-1; i++) { for (int j=1; j<v.length-i; j++) { if (v[j-1].esMayorQue(v[j])) { Ordenable temp = v[j]; v[j]=v[j-1]; v[j-1]=temp; } } } } class Fraccion implements Ordenable { public boolean esMayorQue( Ordenable o ) { if (o instanceof Fraccion) { Fraccion f2 = (Fraccion) o; return (1.0*num/den > 1.0*f2.num/f2.den); } else return false; ... Programación III Tema 3 - Interfaces
  • 24.
    El por quéde los interfaces (1) • Herencia Múltiple – Una clase tiene más de un padre – Presenta problemas cuando: • Se heredan varias implementaciones para un mismo método • Se heredan varias copias de un mismo atributo • Ejemplo: Vehiculo VehiculoTerrestre VehiculoAcuatico Coche VehiculoAnfibio Barco Programación III Tema 3 - Interfaces
  • 25.
    El por quéde los interfaces (2) • Complejidad (Eiffel, C++): – Si la clase Vehículo tuviera un atributo llamado matrícula, ¿Cuántas matrículas tendría la clase VehiculoAnfibio? – ¿Si Vehículo tuviera un método implementado de forma diferente por VehiculoTerrestre y por VehiculoAcuatico? • Java no permite la herencia múltiple – ¿Cómo resuelve Java estas jerarquías? – Mediante otro mecanismo: los interfaces Programación III Tema 3 - Interfaces
  • 26.
    ¿Qué es uninterface? • Es un conjunto de métodos – Sólo cabeceras, sin implementación – Definen un comportamiento específico para un conjunto de objetos • Es una forma de crear tipos (como las clases) – Se pueden declarar variables – Se pueden declarar métodos • Y debido a esto: – Sus métodos son “abstractos” – No se pueden instanciar (como las clases abstractas) – No se hereda codificación, sólo definición Programación III Tema 3 - Interfaces
  • 27.
    Definición de interfaces • Palabra reservada interface seguida de una lista de métodos (cabeceras) sin implementación • Ejemplo 1: interface UnInterface { void mensaje1(); void mensaje2(); } • Ejemplo 2: interface Driveable { boolean startEngine(); void stopEngine(); float accelerate(float acc); boolean turn(Direction dir); } • Todos los métodos de un interface son públicos Programación III Tema 3 - Interfaces
  • 28.
    Implementación de interfaces(1) • Para “implementar” un interface: – Cláusula implements – Cuando se relaciona una clase con una interfaz y no se implementan los métodos, la clase pasa a ser “abstracta” (no se puede instanciar). • Ejemplo 1: class UnaClase implements UnInterface { void mensaje1() { System.out.println(“1”); } void mensaje2() { System.out.println(“2”); } } • Ejemplo 2: class Automobile implements Driveable { public boolean startEngine() { if (notTooCold) engineRunning = true; ... } public void stopEngine() { ... engineRunning = false; } public float accelerate(float acc) { ... } public boolean turn(Direction dir) { ... } } Programación III Tema 3 - Interfaces
  • 29.
    Implementación de interfaces(2) • En estos momentos: – La clase Automobile implementa el interface Driveable – La clase Automobile posee un tipo “extra”: El tipo Driveable – Todos los objetos de la clase Automobile pertenecen también al tipo Driveable • Un interface puede ser implementado por más de una clase class Automobile implements Driveable { ... } class LawnMower implements Driveable { ... } – En cualquier lugar donde se requiera un objeto del tipo Driveable podremos situar un objeto de la clase Automobile o de la clase LawnMower. De esta forma nos aseguramos que los métodos existen aunque no nos preocupa su implementación real. Estamos definiendo una API, una interfaz de programación que asegura un concepto, no una implementación concreta. Automobile auto = new Automobile(); Lawnmower mower = new Lawnmower(); Driveable vehicle; vehicle = auto; vehicle.startEngine(); vehicle.stopEngine(); ... vehicle = mower; vehicle.startEngine(); vehicle.stopEngine(); Programación III Tema 3 - Interfaces
  • 30.
    Interfaces - ejemplo • interfaz Comparable – Método int compareTo(Object o) • Devuelve -1, 0, +1 • Todas las clases que sean ordenables pueden implementar este interfaz • ¿Qué ventajas tiene el programador? – Regularidad: siempre se compara igual – Polimorfismo: • void ordenaGrupo( Comparable c[] ) Programación III Tema 3 - Interfaces
  • 31.
    Implem. de interfacesmúltiples (1) • Una clase puede implementar más de un interface (herencia múltiple) – Ejemplo 1: interface A { void mensaje1(); void mensaje2(); } interface B { void mensaje3(); void mensaje4(); } class C implements A, B { void mensaje1() {System.out.println(“1”);} void mensaje2() {System.out.println(“2”);} void mensaje3() {System.out.println(“3”);} void mensaje4() {System.out.println(“4”);} } Programación III Tema 3 - Interfaces
  • 32.
    Implem. de interfacesmúltiples (2) – Ejemplo 2: • Tenemos un nuevo interface: el interface Cloneable interface Cloneable { Object clone(); } • Tenemos una clase base para todos los tipos de vehículos llamada Vehicle • Definamos Automobile: class Automobile extends Vehicle implements Driveable, Cloneable { ... public boolean startEngine() { ... } public void stopEngine() { ... } public float accelerate( float acc ) { ... } public boolean turn( Direction dir ) { ... } public Object clone() { ... } } • Automobile debe implementar los métodos de todos los interfaces que implemente si se quiere poder instanciar objetos de tipo Automobile. • Los objetos de la clase Automobile pertenecerán a 4 tipos distintos (se podrán usar como si fueran de cualquiera de esos tipos): – El tipo Automobile – El tipo Vehicle – El tipo Driveable – El tipo Cloneable Programación III Tema 3 - Interfaces
  • 33.
    Herencia de interfaces • Los interfaces pueden heredar mediante extends interface A { void mensaje1(); } interface B extends A { void mensaje2(); } • Una clase que implemente el interface B deberá implementar los métodos de ambos interfaces si quiere poder crear objetos. class C implements B { void mensaje1() {System.out.println(“1”);} void mensaje2() {System.out.println(“2”);} } • Además, Java admite la herencia múltiple entre interfaces interface A { void mensaje1(); } interface B extends A { void mensaje2(); } interface C extends A { void mensaje3(); } interface D extends B, C { void mensaje4(); } • La clase que implemente el interface D deberá implementar los 4 métodos si quiere que se puedan instanciar objetos. Programación III Tema 3 - Interfaces
  • 34.
    Ejemplo: Interfaces yclases abstractas interface ElementoVolador { void acelerar( int vel ); } interface ElementoMecanicoVolador extends ElementoVolador { void arreglarMecanismos(); } abstract class Avion implements ElementoMecanicoVolador { boolean elMotorFunciona; public void arreglarMecanismos() { elMotorFunciona = true; } } class AvionComercial extends Avion { int velocidad; public void acelerar( int vel ) { velocidad += vel; } } Programación III Tema 3 - Interfaces
  • 35.
    Ejercicios propuestos (1) • Implementación de Enumeration • Queremos incorporar en la clase ListaEnlazada el interface de java.util.Enumeration. Para ello: – Definiremos una clase de paquete EnumeradorLista que implemente el interface de Enumeration sobre una lista enlazada. Esto es, tiene que tener un constructor que inicialice la secuencia, un método de comprobación de final hasMoreElements() y un método de extracción del siguiente elemento de la secuencia nextElement(). – Para evitar que esta clase la tenga que manipular directamente el usuario incorporaremos a la clase ListaEnlazada un método enumeracion() que devuelva una instancia de EnumeradorLista inicializada sobre la propia lista. – Así, desde un programa podremos para recorrer cualquier lista y hacer algo así como: java.util.Enumeration e = l.enumeracion(); while (e.hasMoreElements()) { System.out.print( " " + e.nextElement() ); } – Esta clase EnumeradorLista es el clásico ejemplo de uso de clase interna. Probar a definirla así. – Cambiar la clase ListaEnlazada de acuerdo a todo esto. Probar en el main que efectivamente la enumeración funciona. Programación III Tema 3 - Interfaces
  • 36.
    Ejercicios propuestos (2) • Jerarquía de figuras – Crear una clase llamada Figura de la que extiendan las clases Cuadrado, Triángulo y Círculo. Figura debe ser una clase abstracta que contenga dos métodos void dibujar() y void borrar(). Por otro lado, cada clase descendiente de Figura va a redefinir estos métodos visualizando por pantalla, en cada caso, un mensaje. • (Por ejemplo: “Dibujando cuadrado/triángulo/círculo”, “Borrando cuadrado/triángulo/círculo”). – Crear por otro lado una clase Pizarra que tenga un atributo que sea un array de Figuras. Además, tendrá un método para añadir Figuras al array y otro para borrar todas las figuras del array. • Para probar el funcionamiento, realizar una clase Ejemplo que añada varias figuras (de cualquier tipo) a la pizarra. Ir viendo lo que saldría por pantalla para ver cómo funciona el polimorfismo. También se puede llamar al método borrar de la clase Pizarra para ver cómo se irían borrando todas las figuras. – Jerarquía de figuras + Interfaces • Modificar el ejercicio anterior de la siguiente forma: – Definir un interface llamado Coloreable que hace referencia a todos los objetos que admiten un color, definiendo los métodos void cambiaColor( Color c ) que cambia el color del objeto y el Color queColor() que devuelve el color del objeto. – Hacer que Figura implemente el interfaz Coloreable, añadiendo los métodos y atributos necesarios. ¿Dónde implementarías estos métodos? Hazlo. Programación III Tema 3 - Interfaces