Interfaces

Recordemos para que servían añadir “abstract”:

“Para evitar que se puedan generar objetos de la clase padre si es que no se quiere se tiene que añadir  Abstract de esta manera lo que se hará es que para esta clase será imposible instanciar objetos”.

En Java, una clase sólo tiene una superclase. No existe la herencia múltiple. Para solucionar las situaciones en las que es necesario definir una clase con características definidas en  más de una clase, se emplean interfaces.

Una interfaz es una colección de constantes y métodos abstractos.

No es una clase, sirven como guía, pero tienen varias limitantes:

  • No pueden contener atributos ni constructores y solo se pueden hacer métodos abstractos, que no se inicializan, es más ni siquiera se tiene que poner esa palabra.
  • Es imposible poder crear un objeto de esa clase.

Sintaxis:

public interface NombreDeInterfaz{
    public Constantes;
public MetodoAbstracto(…);
}

Para implementar una interfaz se usa la siguiente sintaxis:

public class ClaseHija implements NombreDeInterfaz{
   //Contenido de Clase
}
public class ClaseHija extends ClasePadre implements Interfaz1, Interfaz{
   //Contenido de Clase
}

¿Para que sirven?

Espera, espera, espera ¿Para que demonios quiero una interfaz?, digo, si no puedo crear objeto de ella ni atributos, ni anda así ¿para que la necesito?  ¿Porque no se llama interfaz, porque no clase basura o clase inútil?

Pues lo primero de todo es que clase inútil no suena nada mal. Me gusta.

Pero ya enserio, sirven a un solo propósito: Y es que cuando tu “extiendes” o “implementas” de una interfaz hay que redefinir todos los métodos incluidos en la interfaz.TODOS.

Por defecto, todas las interfaces son abstractas y todos los métodos de una interfaz abstractos y públicos, por eso no se especifica explícitamente

Las interfaces pueden formar jerarquías heredando de una interfaz determinada (cláusula extends).

Oye..antes de que te vayas, te daré un secreto…No se pueden instanciar Objetos, sin embargo si es posible hacer:

NombreDeInterfaz Instancia = new NombreDeClaseHija();

Este nuevo objeto, es capaz funciona como una instancia de NombreDeClaseHija siempre que esas referencias estén también en la Interfaz, es decir, si hay un método propio de la clase o un atributo, el programa crashea, pero si solo haces referencia a los métodos que existen en la interfaz, todo esta bien.


Así que en resumen podemos darle estos usos a las interfaces:

  • Como un contrato de Software, que te obliga a implementar unos métodos específicos  con un nombre, tipos de datos de entrada y salida ya definidos, así todo el proyecto queda mas consistente.
  • Permite emular una jerarquia múltiple.
  • Permite el Poliformismo como allá arriba.


Diferencias entre Interface y Clase abstracta

interfaces

Interfaz vs Clase Abstracta… Fight!

La principal diferencia entre interface y una clase abstracta abstract es que un interfaz proporciona un mecanismo de encapsulación de los prototipos de  los métodos evitando al desarrollador forzar  una relación de herencia.

La ventaja principal del uso de interfaces es que una clase interface puede ser implementada por cualquier número de clases, permitiendo a cada clase compartir el interfaz de programación sin tener que ser consciente de la implementación que hagan las otras clases que implementen el interface.

Una clase abstracta puede incluir métodos implementados y no implementados o abstractos, constantes y otros atributos.

Una clase solamente puede derivar (extends) de una clase base, pero puede implementar varios interfaces. Los nombres de los interfaces se colocan separados por una coma después de la palabra reservada implements.

El lenguaje Java no fuerza por tanto, una relación jerárquica, simplemente permite que clases no relacionadas puedan tener algunas características de su comportamiento similares.

Y ya, lo has logrado

¿No fue divertido?

lisa.jpg

 

 

btn1 btn
btn

Herencia

Relaciones entre Clases

Antes de entrar de lleno a herencia, vamos a ver las relaciones entre las clases, pues resulta ser que aunque la herencia es la más útil, la más famosa y la que mas te va a importar no es la única.

Esta jerarquía de clasificación es  subjetiva, dependiendo de las intenciones con las que se pretenda trabajar. Es muy difícil establecer una relación perfecta y surgen elementos que no se acomodan en ninguna categoría.

Agregación / Composición

“todo – parte / tiene-un / parte-de”

Esta relación se presenta entre una clase TODO y una clase PARTE que es componente de TODO. La implementación de este tipo de relación se consigue definiendo como atributo un objeto de la otra clase que es parte-de.

Los objetos de la clase TODO son objetos contenedores. Un objeto contenedor es aquel que contiene otros objetos.

Tipos

  • Contenido Físico- Valor

El contenedor contiene el objeto en sí. Cuando creamos un objeto contenedor, se crean también automáticamente los contenidos.

  • Conceptual – Referencia

Se tienen punteros a objetos. No hay un acoplamiento fuerte. Los objetos se crean y se destruyen dinámicamente. La relación de agregación/composición establece jerarquías de clases por grado de composición.

El ejemplo más clásico de esto es el del motor y un auto:


Asociación

Es una relación entre clases. Implica una dependencia semántica. Son relaciones del tipo “pertenece a” o “está asociado con”. Se da cuando una clase usa a otra clase para realizar algo.


Herencia

viejo

¡Respeta a la Clase Padre!

La herencia es un mecanismo fundamental en la construcción de clases, necesario para reutilizar código. Mediante la herencia podemos crear clases nuevas a partir de otras que ya existen, sin necesidad de reescribir todo el código: mecanismo de reutilización de código.

Mediante la herencia podemos organizar las distintas clases en estructuras jerárquicas.

Algo especializado va a heredar de algo general, como un coche de un vehículo, o un loro de un ave. Esto se hace en programación porque se suelen tener muchas cosas en común pero no todas. 

Entonces lo que se hace es poner todas las características en común de los objetos en una clase “Padre” de la que todos va a heredar.

herencia1

Entonces al decirte a Java que es una clase hija, esta nueva clase ahora es capaz de acceder a todos los atributos, interfaces implementadas y todos los métodos que tiene su padre, siempre que sean públicos o protegidos.

Sintaxis

Para que Java sepa que una clase es hija se declara la clase de la siguiente manera:

public class ClaseHija extends ClasePadre{
   //Contenido de Clase
   ...
}

De este modo ahora ahora la clase hija se refería bajo esta nomblecaruta:

  • Super: Clase Padre
  • This: Clase Propia

Constructor de una Clase Hija

public class ClaseHija extends ClasePadre{                //Constructor
   public NombreClase(Tipo Algo1,Tipo Algo2,Tipo Algo3){
       Super(Algo1, Algo2)                                //Atributos Extendidos
       this.Algo3 = Algo3;                                //Atributos Unicos
   }
}

Recuerda que Super simpre tiene que ir al principio del Constructor.


Clases Abstractas

“¡Timmy! ¿Qué demonios es un objeto Vehículo marino? ¡Eso no existe! ¿Quién permitió que esto fuera posible de hacerse”

Para evitar que se puedan generar objetos de la clase padre si es que no se quiere, se tiene que añadir Abstract de esta manera lo que se hará es que para esta clase será imposible instanciar objetos.

public abstract class NombreDeClase{
   ...
}

Métodos Abstractos

Son necesarios crear algo así, déjame te explico:

NombreDeClasePadre Instancia = new NombreDeClaseHija();

Y que no den ningun error hay que implantar tener en cuenta que:

  • No se puede llamar a un método si no existe en la clase Padre a pesar de ser un objeto de la Clase Hija.
  • Si existe en ambos el mismo método se llama al de la Clase Hija.

Para cumplir esto es necesario crear clase abstractas que existan en el Padre, pero que no hagan nada, simplemente que obligan a las clases hijas a añadirlas.

public abstract NombreDeClase();


Herencia en Varios Niveles

Es posible en Java crear herencias en varios niveles, es decir que ahora la clase nieta es capaz de acceder a todos los atributos y todos los métodos que tiene su padre y su abuelo siempre que sean públicos o protegidos.

herencia2

Sintaxis:

public class ClaseAbuelo{
//Contenido de Clase
}
public class ClasePadre extends ClaseAbuelo{
//Contenido de Clase
}

public class ClaseNieta extends ClasePadre{
//Contenido de Clase
}

La  herencia es al final del día:

HERENCIA = TRANSMISIÓN + REDEFINICIÓN + ADICIÓN

Es decir, la herencia te permite TRANSMITIR todos los métodos y atributos de una clase padre a la mía, REDEFINIR varios métodos de la clase padre si así lo deseo  y AÑADIR más si requiero más.

 

btn1 btn
btn

Polimorfismo

Es Polimorfismo es la capacidad que tiene un lenguaje de programación, en este caso Java, elegir uno u otro método en función del contexto.

mariposa

La SobreCarga

Es posible en Java crear dos métodos con el mismo nombre pero que reciben un tipo de dato diferentes, es decir con un parámetro diferente, es decir este ejemplo es posible:

//METODO #1
public void MétodoX(int Numero){
  Sentencias;
  ...
}

//METODO #2
public void MétodoX(String Frase){
  Sentencias;
  ...
}

Y el programa será capaz de decidir a cuál método nos referimos simplemente por el tipo de datos que le pasemos como parámetro.


La SobreEscritura

Es posible en Java crear dos métodos con el mismo nombre y que reciben un tipo de datos usando Herencia (ya lo verás después) entonces dependiendo de si llamas a la un objeto de la clase hija o padre accederás a uno u otro método.

sobrecarga

Adios al viejo método

Es decir, se puede crear en una clase hija otro método con el mismo nombre y parámetros que un método en la clase padre, y entonces se dice que este método se ha sobrescrito.


Polimorfismo en POO

Es posible crear objetos en referencias de los padres, es decir:

NombreDeClasePadre Instancia = new NombreDeClaseHija();

Esto es útil para hacer vectores de objetos y demás, en el caso de que esto sea así se seguirán las siguientes reglas:

  • No se puede llamar a un método si no existe en la clase Padre a pesar de ser un objeto de la Clase Hija.
  • Si existe en ambos el mismo método se llama al de la Clase Hija.
btn1 btn
btn

Métodos y Constructores

constructores

Métodos

Los métodos son la siguiente parte importante de todo esto, representan las acciones que nuestro objeto puede hacer:

Es el nombre de las funciones en Java. Su sintaxis es:

public Tipo nombreDeMétodo(){
     sentencias;
     ...
     return Atributo
}


Métodos Especiales

Cuando se coloca un atributo en Java en privado para poder acceder a el se hacen métodos o funciones que dan permisos de Leer y Escribir (o llamadas GET y SET).

Métodos GET

Este tipo de funciones lo que devuelve es el atributo deseado, para que lo puedan ver desde fuera de la clase pero no puedan modificarlo.

public Tipo getAtributo(){
    return Atributo;
}

Ejemplo:

//Ejemplo 1
public String getNombre(){
    return Nombre;
}

//Ejemplo 2 (Usando Constructores)
public Tipo getAtributo(){
    return new Tipo(Atributo);
}

//Ejemplo 3 (Usando Constructores de Copia)
public vertice getA(){
    return new vertice(a);
}

Métodos SET

Este tipo de funciones lo que hace es darle valor a un atributo deseado, para que lo puedan ver desde fuera de la clase pero no puedan modificarlo.

Nota: Al referirnos al this.Atributo lo que estamos haciendo es referirnos al atributo de la clase, y al solo poner Atributo dentro del método nos referimos al atributo que acabamos de crear como parámetro del método.

public void setAtributo(){
     this.Atributo = Atributo;
}

Ejemplo:

//Ejemplo 1
public void getNombre(String Nombre){
   this.Nombre = Nombre;
}


Métodos de Object

Todos los objetos en Java son hijos de la clase Object, por lo que existen unos métodos bastante comunes que nosotros podemos sobre escribir y que nos muy útiles.

Método toString()

Cuando tu colocas el nombre de tu objeto donde venia ir un string se llama de forma automática este método. Generalmente se espera que regrese un string.

Método equals()

Es muy común que se llame para saber si dos objetos con lo “mismo” tu puedes modificarlo según lo que para ti se considere que tu objeto sea “igual” al otro.

Método finalize()

Se llama al colector de basura, nos permite guardar el estado o datos que creemos que son necesarios conservar antes de “borrar” un objeto.


Constructor

constructores

Es un método que evita tener que llenar los valores de cada objeto. Suele ser el primer método que se encuentra en cada clase, justo después de la declaración de atributos.

Aquí te coloco sus características mas comunes:

  • Tiene el mismo nombre que la clase
  • Generalmente es público
  • Su objetivo (su motivo en la vida) es inicializar el estado de los atributos de una clase
  • Se puede sobrecargar

Forma Básica

public NombreClase(Tipo Algo1, Tipo Algo2){
   this.Algo1 = Algo1;
   this.Algo2 = Algo2;
}

Constructores de Copia

Este tipo de constructores se usan cuando se crean objetos de objetos, decir, y valga la redundancia, copia o clona un objeto que ya existe.

Este tipo de constructores permiten crear objetos que serán independientes de sus paramentos una vez creados, pues de otra manera si se modificarán los atributos que usa un constructor para crear un objeto, los atributos del objeto en sí serán cambiados.

Usado cuando se crean objetos que reciben como parámetros de creación otros objetos.

public NombreClase(NombreClase ObjetoACopiar){
Algo1 = ObjetoACopiar.Algo1();
Algo2 = ObjetoACopiar.Algo2();
...
}

Ejemplo:

public Triangulo(Punto 1, Punto 2, Punto 3){
this.1 = new Punto(1);
this.2 = new Punto(2);
this.2 = new Punto(3);
}

Entonces no se llaman ya a los métodos SET and GET sino solo:

clase Nombre = new clase(Algo1,Algo2...)

Tipo NO tiene porque ser sólo int o strings sino que puede recibir objetos de tipos que hemos creado como autos o figuras.


Destructor

Java no tiene en si un destructor, pero si que tiene algo muy parecido, te mostrare:

public void Destruir(){
Algo1 = null;
Algo2 = null;
System.gc();
}

Sobrecarga de Métodos

Finalmente algo muy importante de lo que hablar es de la sobrecarga que permite que existan en una clase varios métodos que se llamen diferente y permite una mayor versatilidad.

Si principal ventaja es que permite reutilizar muchísimo código.

Hay varias características:

  • No importan si unos son public o private
  • Igual tipo de datos devuelto
  • Igual nombre del método
  • Distintos parámetros

Por ejemplo, veamos la clase de Ejemplo:

package LogicaDelSistema;

public class Persona {

    // ====== Atributos =====
    private int edad;
    private String nombre;
    private boolean sexo;

    // === Constructor ======
    public Persona(){
        this(0,"",false);

    }
    // === Constructor SobreCarga ===
    public Persona(int edad, String nombre, boolean sexo){
        this.edad = edad;
        this.nombre = nombre;
        this.sexo = sexo;
    }
    // === Constructor Copia ===
    public void setPersona(Persona PersonaOriginal){
        this.edad = PersonaOriginal.edad;
        this.nombre = PersonaOriginal.nombre;
        this.sexo = PersonaOriginal.sexo;
    }
    // === Constructor SET ===
    public void setPersona(int edad, String nombre, boolean sexo){
        this.edad = edad;
        this.nombre = nombre;
        this.sexo = sexo;
    }

    public String toString(){
        String mensaje;
        if(sexo){mensaje= "Hombre";}
        else{mensaje = "Mujer";}
        return "Edad:"+edad+"\n"+"nombre:"+nombre+"\n"+"sexo:"+mensaje;
    }

    public void Comer(){
        System.out.print("Comiendo ");
    }

    public void Comer(String comida){
        Comer();
        System.out.print(comida);
    }

    public void Comer(String comida, String amigo){
        Comer(comida);
        System.out.print(" con "+amigo);
    }

}


Sobrecarga de Operadores

Naaaaaahh…. Java no la tiene XD.

Pero aun así es un tema muy interesante, así que solo, SOLO con este tema te contaré lo que hace C++.

Así que olvida por un rato que estamos en Java y veamos como lo hace la competencia:

Por ejemplo, veamos la clase de Ejemplo:

tipo nombre_clase::operator + (lista de parámetros);

Podemos ver distinguir entre 2 Operaciones:

Los operadores binarios se declaran con un solo parámetro, ya que el primer parámetro es pasado por el programa como this, es decir, un puntero al mismo objeto.

// Binario
Objeto Objeto::operator + (Objeto &B);
Objeto A, B, C;
C = A + B;               // C = A.operator+(&B);

Los operadores unarios se declaran sin paramétros, ya que el único parámetro es pasado por el programa como this.

// Unario
Objeto Objeto::operator ++ (int Basura);
Objeto A, C;
C = A++;                 // C = A; A = A + 1;
C = A++;                 // C = A.operator++(int Basura);

This vs *This

class Foo {
    public:
        Foo(){
            this->value = 0;
        }

        Foo tenCopia(){
            return *this;
        }

        Foo& copiaComoReferencia(){
            return *this;
        }

        Foo* tenPuntero(){
            return this;
        }

        void aumenta(){
            this->value++;
        }

        void imprime(){
            std::cout<< this->value << "\n";
        }
}

Así podemos ver que:

int main(){
    Foo foo;
    foo.aumenta();
    foo.imprime();

    foo.tenCopia().aumenta();
    foo.imprime();

    foo.copiaComoReferencia().aumenta();
    foo.imprime();

    foo.tenPuntero()->aumenta();
    foo.imprime();

    return 0;
}

Así tenemos este resultado:

1
1
2
3
btn1 btn
btn

Tipos de Abributos

Recordemos algo antes de empezar…

Principios de Encapsulamiento

Este principio dice que todos lo atributo que se relacionan a una clase tiene que estar declarados dentro de la misma clase.

cad

Hoy vamos ver un tema muy importante:

Ocultación de Información

En Java podemos tener varios tipos de atributos dependiendo de que tan disponibles están para nuestro programa.


Public

Es el característica por defecto en Java, que un atributo tenga esta propiedad significa que es posible acceder a el desde fuera  de la clase de la forma:

//Puedo hacer esto
Instancia.Atributo


Private

Que un atributo tenga esta propiedad significa que será imposible acceder a el desde fuera  de la clase de la forma:

//No Puedo hacer esto
Instancia.Atributo


Static

Que un atributo tenga esta propiedad significa que todos los objetos de su misma clase ahora tendrán el mismo valor en ese atributo o en ese método. Es decir que TODOS los objetos de esa clase tendrán un solo atributo.

  • Se coloca después de Public/Private.
  • Son muy comunes para comunicar a varios objetos de una clase.
  • Pueden crear métodos con esta característica y se pueden acceder incluso sin instanciar un objeto.
public static Atributo
private static Atributo

Final

Que un atributo tenga esta propiedad significa que no podrá modificarse el valor de este atributo una vez puesto.

  • Se coloca después de Public/Private.
public final Atributo
private final Atributo

Sin embargo si se coloca en un metodo este metodo ya no se podrá sobrescribir:

public final Metodo
private final Metodo

Protected

Que un atributo tenga esta propiedad significa que solo lo podrán modificar el ó las clases que hereden de el.

  • Se coloca después de Public/Private.
protected Atributo

 

 

 

btn1 btn
btn

Clases y Objetos en Java

Ahora si, hasta ahora Java no se veía muy diferente de C, pero eso esta por cambiar, vengan niños, les contare la historia de cuando Java conoció a POO…

hymym

¡¿No ven su cara de diversión?!


Clases

La clase es un forma de representar un objeto o concepto de la realidad, como una estructura en C. Se crea una clase con la sintaxis:

public class NombreDeClase{
  public  Atributo1;

  private Atributo2;
  private Atributo3;

  public void MuestraX(){
    ...
  }
}

Si tu generas una clase todos los métodos de la misma tendrán acceso a los atributos de la clase.

 

 


Objetos

También se las conoce como instancias.

Son las variables o instancias que creemos de una clase.

clases.png

//Sintaxis Crear un Objeto:
NombreDeClase Instancia;

//Crearlo e Inicializarlo:
NombreDeClase Instancia = new NombreDeClase();

Igualar 2 Objetos

Cuando se igualan 2 objets o que se igualan son sus direcciones de memoria y por lo tanto ahora están enlazados y si se cambia un valor a uno el otro tan sufre este cambio. La orden this.Algo1 hace referencia a su dirección de memoria yes debido a estar que se entrelazan los objetos.


Arrays de Objetos

Sintaxis:

NombreClase[] nombreVector = new NombreClase[tamaño];

 

 

btn1 btn
btn

Try Catch

try

Son una herramienta que evita que un programa se quede congelado o de un error.

 

//SINTAXIS SIMPLE
try {
   CodigoProblematico
   ...
}
catch(Exception Nombre){
   CodigoSolucion
}

//SINTAXIS COMPLEJA
try {
   CodigoProblematico
   ...
}
catch(TipoDeErrores Nombre){
   CodigoSolucion1
}
catch(Exception Nombre){
   CodigoSolucion2
}
finally{
   Código que siempre se ejecuta
}

Donde:

  • CodigoProblematico: Es el código  Peligroso o que daría problemas, al momento de dar problemas se accede a Catch
  • CodigoSolucion1: Si da un problema el código del Try, se deja de ejecutar y se procede a correr esta parte del código y todos felices.
  • CodigoSolucion2: Si da un problema el código del Try, se deja de ejecutar y se procede a correr esta parte del código y todos felices.
btn1 btn
btn