1. Clases contra Interfaces
Clases
Las clases son plantillas de objetos. Definen el tipo de objetos, que datos que contendrá y
los métodos para operar con esos datos. Un ejemplar de esa clase es la plantilla rellena con
los datos y las llamadas a los métodos-- el ejemplar (copia) es el objeto.
Podemos crear muchos ejemplares de la misma clase, creando muchos objetos de ese tipo.
Cada objeto tiene sus propios datos, y algunos objetos comparten datos específicos,
dependiendo de si han sido declarados datos static o instancias. Esto lo explique con el
ejemplo de valor y referencia para determinar la dimensión de una matriz.
Creación de varios ejemplares de clase, por medio de instancia. Donde los parámetros se
utilizan por valor.
En este caso se elabora clase abtrascta con datos static, donde se siempre se solicitan los
datos de la dimensión matriz y se almacenan en una referencia de memoria, no es necesario
instanciar.
2. Herencia
No tenemos que escribir una clase desde el principio. Si ya existe una clase que tiene
características similares a la que queremos crear, podemos usar la palabra clave extends
para heredar campos y métodos desde otra clase. Luego añadimos mas campos y métodos
para crear una clase más rica que la clase padre. Pero no tenemos que conformarnos con los
campos o métodos heredados. Podemos sobreescribir métodos(Polimorfismo), u ocultar
datos de las clases padre(Encapsulamineto) para cumplir con nuestras necesidades.
Cada vez que se tiene una clase que hereda un método de una superclase, se tiene la
oportunidad de sobreescribir el método (a menos que dicho método esté marcado como
final). El beneficio clave al sobreescribir un método heredado es la habilidad de definir un
comportamiento específico para los objetos de la subclase. Veamos un ejemplo de la
sobreescritura de un método heredado:
public class Animal
{
public void comer ()
{
System.out.println("Animal comiendo...");
}
}
class Caballo extends Animal
{
public void comer()
{
System.out.println("Caballo comiendo...");
}
}
Al momento de que Caballo hereda de la clase Animal obtiene el método comer() definido
en Animal, sin embargo, se desea especificar un poco más el comportamiento de Caballo
al momento de llamar a comer(), por lo tanto se define un método con el mismo nombre
dentro de la clase Caballo. Debido a que ambos métodos tienen el mismo nombre, para
saber qué método se invocará en tiempo de ejecución es necesario saber a qué objeto se está
refiriendo. P. ej.:
public static void main(String... args)
{
Animal a = new Animal();
Caballo c = new Caballo();
a.comer();
c.comer();
}
Esto es cierto para clases concretas, pero no para los interfaces.
3. Interfaces
Los interfaces declaran métodos, y posiblemente campos estáticos, pero no definen
métodos. En su lugar, los interfaces sólo declaran los métodos sin ninguna instrucción
dentro de ellos. En otras palabras, los interfaces son como plantillas que siempre serán
plantillas. No podemos ejemplarizar un interface para crear un objeto. Son como clases sin
implementación. ¿Entonces por qué existen?
Sirven para un propósito: para forzar al desarrollador a proporcionar esos métodos, con
detalles, en la clase que implements el interface. En otras palabras, implementar un
interface significa que estamos haciendo la promesa de usar ciertos métodos, pero nosotros,
los desarrolladores, definimos los detalles de esos métodos.
¿Por qué es esto útil o necesario?
Supongamos que tenemos un equipo de desarrolladores que están creando clases para hacer
diferentes tipos de objetos animales. Todos esos animales van a tener dos cosas en común:
Usan alguna foma de locomoción.
Comen alguna clase de comida.
La diferencia entre los animales está en cómo se mueven y qué y cómo comen. En otras
palabras, cada uno necesita tener los métodos locomotion() y eat() , pero cada individuo,
cada clase animal, define los detalles de esos métodos separadametne basándose en las
necesidades de las especies de animales.
Diseñamos un interface para asegurarnos de que cada objeto animal hace ciertas cosas, y
nuestro equipo desarrolla clases como ésta:
4. En el interface Animal, los métodos están declarados, pero no definidos. Observa que esos
métodos (en azul) están definidos en clases concretas Shark y Dog . En el ejemplo de
arriba, cada método imprime una línea de texto, indicando lo que come el animal y como se
mueve desde un lugar a otro. La última clase es una aplicación que inicializa las dos clases
concretas Shark y Dog , y llama a los métodos de esas clases, usando el operador punto.
Cuando compilamos y ejecutamos AnimalTest , obtenemos el siguiente resultado:
I swim. I hunt for seals. I run on four legs. I eat kibble.
Los juegos son otro ejemplo de cómo podríamos implementar interfaces. Por ejemplo,
podríamos diseñar los siguientes juegos: Water Pistol Wars, Asteroid Archery, Rubberband
Rally, y Cannon Craze. Todos implican armas de fuego, pero las armas y lo que disparan
son diferentes. Un interface se podría asegurar de que todo juego implemente un método
fire() , pero es cosa de cada diseñador del juego la forma de disparar y el tipo de munición
utilizada.