INTERFACES y CLASES ABSTRACTAS

 

APARTADOS

Clases abstractas
Interfaces
Diferencias clases abstractas e interfaces

 

Clases abstractas

Se puede definir una clase sin tener que implementar los métodos (por tanto una clase abstracta contendrá métodos abstractos, es decir, métodos sin implementar). Se pueden realizar varias implementaciones de una misma clase abstracta.

No se podrá crear un objeto de una clase abstracta, antes habrá que crear una clase que herede de la clase abstracta.

Una clase abstracta es muy similar a lo que en C++ se denomina funciones virtuales.

//Descripción: Ejemplo de clase abstracta
//Autor: Daniel Leyva Cortés
//Contacto: transistor47@hotmail.com

import java.io.*;

//La clase abstracta tendrá que iniciarse con la palabra reservada "abstract"
abstract class claseAbstracta
{
//Se pueden declarar cualquier tipo de propiedades en la clase abstracta
public double x, y;
public cEntrada entrada;

//Pueden coexistir métodos implementados con no implementados

  public void recogeValores()
{
    x = Double.parseDouble(entrada.leeCadena());
y = Double.parseDouble(entrada.leeCadena());
  }
public void visualizaValores()
{
    System.out.println("**************************");
System.out.println("Coordenada x: " + x);
System.out.println("Coordenada y: " + y);
  }

abstract public double superficie();

}

//Habrá que realizar herencia de la clase abstracta para poder usarla
class cCirculo extends claseAbstracta
{
final double PI=3.1415;
double radio;

//Realmente se ha implementado un único procedimiento

  public void recogeValores()
{
    entrada =new cEntrada();
super.recogeValores();
radio = Double.parseDouble(entrada.leeCadena());
  }
public void visualizaValores()
{
    super.visualizaValores();
System.out.println("Radio: " + radio);
  }

public double superficie()
{
    return(radio*radio*PI);
  }

}

class cRectangulo extends claseAbstracta
{
double lado1, lado2;
double x2, y2;

  public void recogeValores()
{
    entrada =new cEntrada();
super.recogeValores();
x2 = Double.parseDouble(entrada.leeCadena());
y2 = Double.parseDouble(entrada.leeCadena());
lado1 = Double.parseDouble(entrada.leeCadena());
lado2 = Double.parseDouble(entrada.leeCadena());
  }
public void visualizaValores()
{
    super.visualizaValores();
System.out.println("Coordenada x2: " + x2);
System.out.println("Coordenada y2: " + y2);
System.out.println("Primer lado: " + lado1);
System.out.println("Segundo lado: " + lado2);
  }
public double superficie()
{
    return(lado1*lado2);
  }
}

class usaClaseAbstracta
{

  public static void main(String args[])
{
    cRectangulo rectangulo = new cRectangulo();
cCirculo circulo = new cCirculo();

rectangulo.recogeValores();
rectangulo.visualizaValores();
System.out.println("Superficie: " + rectangulo.superficie());

circulo.recogeValores();
circulo.visualizaValores();
System.out.println("Superficie: " + circulo.superficie());

  }

}

class cEntrada
{
InputStreamReader entrada;
BufferedReader bufferEntrada;

  public cEntrada()
{
    entrada = new InputStreamReader(System.in);
bufferEntrada = new BufferedReader(entrada);
  }
public String leeCadena()
{
    String cadena = new String("");
try
{
      cadena = bufferEntrada.readLine();
    }
catch(java.io.IOException excepcionProducida )
{
      System.err.println("Problema al intertar leer de la entrada estándar...");
    }
return new String(cadena);
  }    
}      

Interfaces

Un interface es un conjunto de definiciones de métodos y de constantes. Los métodos no estarán implementados.

Las interfaces pueden ser implementadas por cualquier clase, permitiendo que aunque existan muchas implementaciones de los mismo métodos éstas tengan el mismo formato (número de parámetros del método, tipo de dato devuelto, nombre del método, etc...), es decir, la misma interfaz.

La sintaxis para declarar una interfaz es la siguiente:

[public] interface nombreInterfaz [extends listaSuperInterfaces]

Una interfaz puede extender de otras interfaces con el objetivo de añadir más métodos a la misma o subclasificarla, para ello se usará la palabra reservada "extends" seguida de la lista de interfaces de las cuales se quiera extender.

Las clases que quieran usar la interfaz tendrán que usar la palabra reservada "implements" y especificar el código de los métodos que están definidos en la interfaz:

//Descripción: Ejemplo de interfaz
//Autor: Daniel Leyva Cortés
//Contacto: transistor47@hotmail.com
import java.io.*;

//Definición de interfaz
interface interfazEjemplo
{
//IMPORTANTE: Si declaras una variable, te obliga a asignarle un valor inicial y además es tratada como CONSTANTE
//Si quisiéramos declarar dos variables x, y tendríamos que hacerlo de la siguiente manera:
// public double x=0, y=0; pero NO PODRÍAMOS MODIFICAR SU VALOR. Por tanto es equivalente escribir "final double PI=3.1415;" y "
double PI=3.1415"
final double PI=3.1415;

  public void recogeValores();
public void visualizaValores();
public double superficie();
}

//Implementación de la interfaz
class cCirculo implements interfazEjemplo
{
public double x=0, y=0;
double radio;
cEntrada entrada;

  public void recogeValores()
{
    entrada =new cEntrada();
x = Double.parseDouble(entrada.leeCadena());
y = Double.parseDouble(entrada.leeCadena());
radio = Double.parseDouble(entrada.leeCadena());
  }
public void visualizaValores()
{
    System.out.println("****************************************");
System.out.println("Coordenada x: " + x);
System.out.println("Coordenada y:" + y);
System.out.println("Radio: " + radio);
  }

public double superficie()
{
    return(radio*radio*PI);
  }

}

class usaInterfazEjemplo extends cCirculo
{

  public static void main(String args[])
{
    cCirculo circulo = new cCirculo();

circulo.recogeValores();
circulo.visualizaValores();
System.out.println("Superficie: " + circulo.superficie());

  }

}

class cEntrada
{
InputStreamReader entrada;
BufferedReader bufferEntrada;

  public cEntrada()
{
    entrada = new InputStreamReader(System.in);
bufferEntrada = new BufferedReader(entrada);
  }
public String leeCadena()
{
    String cadena = new String("");
try
{
      cadena = bufferEntrada.readLine();
    }
catch(java.io.IOException excepcionProducida )
{
      System.err.println("Problema al intertar leer de la entrada estándar...");
    }
return new String(cadena);
  }    
}      

Diferencias clases abstractas e interfaces

Diferencias entre clases abstractas e interfaces:

1) La principal diferencia entre interface y abstract es que un interface proporciona un mecanismo de encapsulación de los protocolos de los métodos sin forzar al usuario a utilizar la herencia.

2)Una clase no podrá heredar de más de una clase abstract, pero sí podrá implementar más de una interfaces. En Java no existe la herencia múltiple. Sin embargo una clase puede "implementar" más de una "interface", siendo ésta una alternativa a la herencia múltiple. Una "interface" puede derivar de otra o incluso de varias interfaces.

3) Una clase no puede heredar métodos "ya implementados" de una interface pero sí constantes.

4) Las interfaces son más flexibles y desvelan menos información

5) Las constantes definidas en una interfaz se pueden utilizar en cualquier clase. Imaginemos que en la interfaz "matematicas" se ha definido la constante "PI", se podría hacer una referencia a dicha constante de la siguiente manera: "matematicas.PI"

EJERCICIO. Implementar la siguiente interfaz (la clase que implemente dicha interfaz tendrá que disponer de un constructor en el cual se le indique el número máximo de elementos que contendrá la tabla):

public interface navegarLista{

//Devuelve verdadero si tiene más elementos por navegar

boolean quedanElementos();

//Devuelve verdadero si está al principio de la lista

boolean esPrincipio();

//Devuelve el elemento actual. Posteriormente apunta al siguiente elemento
float proximo();
//Devuelve el elemento actual. Posteriormente apunta al último elemento
float anterior();

//Inserta un elemento al final de la lista

void inserta(float valor);

//Devuelve el elemento situado en la posición indicada

float consulta(int posicion);

//Extrae el último elemento de la lista

float extrae();

//Devuelve verdadero si la lista está llena

boolean tablaLlena();

}

Volver al sumario