Instituto tecnológico de Tizmin
ing.informática
Roberto Borges Rosado
Arlin Arceo Valle





Herencia


Herencia en la programación orientada a objetos es la habilidad de extender una funcionalidad existente definiendo una nueva clase que hereda funcionalidad de una clase existente. Lo cual nos ahorrara mucho tiempo a los programadores.
Si contamos con una clase que se acerca a lo que necesitamos; no es necesario crear una clase desde cero. Podemos aprovecharla y extenderla para crear nuestra nueva clase. Esta nueva clase se llamara subclase y la clase que ya teníamos se llamara superclase.
La subclase heredara todos los atributos y los métodos que fueron definidos en la clase padre. Si necesitamos cambiar algún método, se puede sobrescribir el comportamiento en nuestra subclase; utilizando el mismo nombre y los mismos argumentos del método que se encuentra en la subclase. O bien si se requiere crear un nuevo método lo podemos incluir en nuestra subclase.
Una clase puede heredar atributos por dos superclases (clases padres). La herencia múltiple puede ser usada para agrupar atributos y métodos de distintas clases en una sola.



Si una clase B hereda de otra clase A entonces:


„ B incorpora la estructura (atributos) y comportamiento (métodos) de la clase A

„ B puede incluir adaptaciones:
„ B puede añadir nuevos atributos
„ B puede añadir nuevos métodos
„ B puede redefinir métodos

 B puede redefinir atributos



class A{
int a=3;
void sumar(){
System.out.println("La suma es: "+(5+3));
}
}

class B extends A{

float a=5.0f;
int x=12;
void sumar(){
int s=0;
for (int i=1;i<=5;i++){
s=s+i;
}
System.out.println("La suma es: "+s);
}

void imprimir(){
System.out.println(“Saludos…”);
}
}




 Reglas básicas para la herencia en Java 

◦ No está permitida la herencia múltiple

 ◦ Si es posible la herencia multinivel, A puede ser heredada por B y C puede heredar de B. ◦ Una clase puede ser heredada por varias clases.

  1. Herencia (clase principal)
  2. acepta
  3. concede
B) La Herencia en java permite que una clase reciba automáticamente  las propiedades y los métodos de otra clase.
C) La clase “concede” tiene el siguiente código con un solo método:
package conceptos;
public class concede { 
    public void estoyEscribiendo(){ 
        System.out.println("Escribonota"); 
    } 
}
D)  Ahora vamos a la clase “acepta” que tiene el siguiente código:
package conceptos;
public class acepta extends concede { 
}
La clase concede utiliza la palabra clave “extends” eso quiere decir que automáticamente la clase “acepta”  recibe todo lo que le da la clase “concede”.
E) La clase principal crearemos una nueva instancia del tipo “acepta” y nuestra clase principal quedara de la siguiente manera:
package conceptos;
public class Herencia { 
    public static void main(String[] args) { 
        acepta herencia = new acepta(); 
        herencia.estoyEscribiendo(); 
    } 
}
Herencia y Constructores 

Los constructores no se heredan • las subclases deben definir su propio constructor Normalmente será necesario inicializar los atributos de la superclase • para ello se llama a su constructor desde el de la subclase /** constructor de una subclase */ public Subclase(parámetros...) { // invoca el constructor de la superclase super(parámetros para la superclase); // inicializa sus atributos ... } 

Modificador de acceso protected 


Modificadores de acceso para miembros de clases: • : accesible desde el paquete • public: accesible desde todo el programa • private: accesible sólo desde esa clase • protected: accesible desde el paquete y desde sus subclases en cualquier paquete Definir atributos protected NO es una buena práctica de programación • ese campo sería accesible desde cualquier subclase - puede haber muchas y eso complicaría enormemente la tarea de mantenimiento • además el campo es accesible desde todas las clases del paquete (subclases o no)


Clases Abstractas
—Las clases abstractas no pueden ser instanciadas.
—Sirven únicamente para declarar subclases que deben redefinir aquellos métodos que han sido declarados abstract.
—Esto no quiere decir que todos los métodos de una clase abstracta deban ser abstractos, incluso es posible que ninguno de ellos lo sea. Aún en este último caso, la clase será considerada como abstracta y no podrán declararse objetos de esta clase.
—Cuando alguno de los métodos de una clase es declarado abstracto, la clase debe ser obligatoria mente abstracta, de lo contrario, el compilador genera un mensaje de error.


Clases final
Una clase declarada final impide que pueda ser superclase de otras clases. Dicho de otra forma, ninguna clase puede heredar de una clase final.

Una clase no puede ser a la vez abstract y final ya que no tiene sentido, pero sí que puede ser public abstract o public final.

Métodos Estáticos


Los métodos static son métodos de clase (no de objeto) y por tanto, no necesita instanciarse la clase (crear un objeto de esa clase) para poder llamar  a ese método. 

final class a{

int x=3;
}
class b extends a{
void imprime(){
System.out.println("x="+x);
}
}
public class ClaseFinal {
    public static void main(String[] args){
b b1= new b();
b1.imprime();   
    }

}

Atributos estáticos

class Persona{
static int objetos_creados=0;
Persona(){
objetos_creados++;
}
}

public class Estaticos {
public static void main(String[] args){
Persona p1= new Persona();
Persona p2= new Persona();
Persona p3= new Persona();
Persona p4= new Persona();
System.out.println("Total de personas creadas: "+p4.objetos_creados);
}
}

Interfaces
Una interface es un conjunto de constantes y métodos abstractos.

Cuando una clase declara una lista de interfaces mediante la cláusula implements hereda todas las constantes definidas en el interface y se compromete a redefinir todos los métodos del interface ya que estos métodos son abstractos (no tienen implementación o cuerpo).

Mediante el uso de interfaces se consigue que distintas clases implementen métodos con el mismo nombre. De esta forma se comprometen a implementarlas. 

A diferencia de las clases, que únicamente pueden heredar de una superclase, las interfaces pueden heredar de varias interfaces mediante la cláusula extends.


La lista de superinterfaces de las que hereda se enumera mediante los nombres de las mismas separados por comas y precedidos por la palabra reservada extends.

Por ejemplo:
public  interface  Operable extends OperableAritmético, OperableLógico {


En este caso, la interface Operable heredaría todas las constantes y métodos de las interfaces OperableAritmético y OperableLógico, pudiendo redefinirse en la interface Operable si fuera necesario.

class Uno {

int y=20;
void saludo(){
System.out.println("Saludo desde la clase Uno");
}
}

interface interface1{

int x=10;
void suma();
}


public class Interfaces extends Uno implements interface1{

public void suma(){
int a=2,b=3;
System.out.println(a+b);
}
public static void main(String[] args){
Interfaces i = new Interfaces();
System.out.println("y:" +i.y);
System.out.println("x:" +i.x);
i.suma();
}

}


Imagen relacionada



Polimorfismo 

En programación orientada a objetos se denomina polimorfismo a la capacidad que tienen los objetos de una clase de responder al mismo mensaje o evento en función de los parámetros utilizados durante su invocación. Un objeto polimórfico es una entidad que puede contener valores de diferentes tipos durante la ejecución del programa.
 Dicho de otra forma, el polimorfismo consiste en conseguir que un objeto de una clase se comporte como un objeto de cualquiera de sus subclases, dependiendo de la forma de llamar a los métodos de dicha clase o subclases. 

El polimorfismo en la sobrecarga sucede cuando existen varios métodos dentro de una clase, todos ellos con el mismo nombre, lo cuál está permitido siempre y cuando los métodos tenga diferente número o tipos de parámetros.


Resultado de imagen para polimorfismo java

Clasificación


Se puede clasificar el polimorfismo en dos grandes

clases:
• Polimorfismo dinámico (o polimorfismo paramétrico) es aquél en el que el código no incluye
ningún tipo de especificación sobre el tipo de datos sobre el que se trabaja. Así, puede ser
utilizado a todo tipo de datos compatible.
• Polimorfismo estático (o polimorfismo ad hoc) es aquél en el que los tipos a los que se aplica
el polimorfismo deben ser explicitados y declarados uno por uno antes de poder ser utilizados.
El polimorfismo dinámico unido a la herencia es lo que en ocasiones se conoce como

Polimorfismo en la sobrecarga

El polimorfismo de sobrecarga ocurre cuando las funciones del mismo nombre existen, con función similar, en clases que son completamente independientes unas de otras (estas no tienen que ser clases secundarias de la clase objeto). Por ejemplo, la clase complex, la clase image y la clase link pueden todas tener la función display. Esto significa que no necesitamos preocuparnos sobre el tipo de objeto con el que estamos trabajando si todo lo que deseamos es verlo en la pantalla. 

class Persona{

void trabaja() { }
void trabaja(int hrs) { }
void trabaja (String lugar, int hrs) { }
}

Persona juan = new Persona();

juan.trabaja();
juan.trabaja(5);

juan.trabaja(“Escuela”,8);

Polimorfismo paramétrico
El polimorfismo paramétrico es la capacidad para definir varias funciones utilizando el mismo nombre, pero usando parámetros diferentes (nombre y/o tipo). El polimorfismo paramétrico selecciona automáticamente el método correcto a aplicar en función del tipo de datos pasados en el parámetro. 

Por lo tanto, podemos por ejemplo, definir varios métodos homónimos de addition() efectuando una suma de valores. El método int addition(int,int) devolvería la suma de dos números enteros. Por su parte, float addition(float, float) devolvería la suma de dos flotantes. En cuanto a char addition(char, char) daría por resultado la suma de dos caracteres definidos por el autor. 

Polimorfismo de subtipado
La habilidad para redefinir un método en clases que se hereda de una clase base se llama especialización. Por lo tanto, se puede llamar un método de objeto sin tener que conocer su tipo intrínseco: esto es polimorfismo de subtipado. Permite no tomar en cuenta detalles de las clases especializadas de una familia de objetos, enmascarándolos con una interfaz común (siendo esta la clase básica).

Para qué nos sirve en la práctica el polimorfismo
Volvamos a la clase "Largometraje" y ahora pensemos en la clase "Cine". En un cine se reproducen largometrajes. Puedes, no obstante, tener varios tipos de largometrajes, como películas o documentales, etc. Quizás las películas y documentales tienen diferentes características, distintos horarios de audiencia, distintos precios para los espectadores y por ello has decidido que tu clase "Largometraje" tenga clases hijas o derivadas como "Película" y "Documental".



programación genérica.




el post anterior Clases y Objetos hablaba como los objetos de nuestros sistema se pueden clasificar de acuerdo a sus atributos y comportamiento. Los objetos de la misma clase se comportan igual y los objetos de diferentes clases se comportan diferente. ¿Parece demasiado obvio verdad? Pues es que lo es.
Por ejemplo, el mecanismo de persistencia ( entiéndase, cuando voy a "salvar", o "guardar" algo ) puede utilizar una base de datos o el sistema de archivos entonces se tendrían dos clases diferentes donde cada una hiciera algo distinto.
Si tuvieramos esta clase llamada Persona:
class Persona {
   private String nombre;
   private String apellido;
   public String nombre()  { return this.nombre; }
   public String apellido()  { return this.nombre; }
}
Podríamos escribir una clase que persistiera personas a una base de datos así:
class GuardaPersonaEnBaseDeDatos {
    void salva( Persona persona ) {
          SomeMagicLibrary.executeUpdate(
                 "UPDATE persona SET nombre = ? , apellido = ? ",
                  persona.nombre(),
                  persona.apellido() );
     }
}
Resultado de imagen para polimorfismo java

Polimorfismo en el reemplazo

Para que Java determine qué métodos debe llamar, debe considerar no sólo los que están dentro de una clase, sino a los que están en las superclases (clase padre).


El reemplazo ocurre cuando un método en una clase tiene el mismo nombre y firma (número, tipo y orden de los parámetros) que un método de una clase padre.


En el caso de que los métodos de la clase padre e hija tengan la misma firma, el método de la clase derivada siempre reemplaza al método de la clase padre.

Tipos de polimorfismo
Sobrecarga (Overloading, Polimorfismo ad-hoc)
 Un sólo nombre de método y muchas implementaciones distintas.
 Las funciones sobrecargadas normalmente se distinguen en tiempo de
compilación por tener distintos parámetros de entrada y/o salida.
Factura::imprimir()
Factura::imprimir(int numCopias)
ListaCompra::imprimir()

Sobre escritura (Overriding, Polimorfismo de inclusión) 

 Tipo especial de sobrecarga que ocurre dentro de relaciones de herencia en métodos con enlace dinámico. 
 Dichos métodos, definidos en clases base, son refinados o reemplazados en las clases derivadas.

Genericidad (plantillas o templates)

 Clases o métodos parametrizados (algunos elementos se dejan sin definir).
 Forma de crear herramientas de propósito general (clases, métodos) y
especializarlas para situaciones específicas.
Lista<Cliente> clientes;
Lista<Articulo> articulos;
Lista<Alumno> alumnos;

ejemplo;

public static main (String[] args) {
Student studentObject = new Student();
Employee employeeObject = new Employee();
//ref apunta a un objeto Student
Person ref = studentObject;
//metodo getName() de la clase Student es invocado
public static main (String[] args) {
Student studentObject = new Student();
Employee employeeObject = new Employee();
//ref apunta a un objeto Student
Person ref = studentObject;
//metodo getName() de la clase Student es invocado
Java 10
//metodo getName() de la clase Student es invocado
String temp= ref.getName();
System.out.println(temp);
//ref apunta ahora a un objeto Employee
ref = employeeObject;
//metodo getName() de la clase Employee es invocado
String temp = ref.getName();
System.out.println(temp);
}


Conclusión

Si parece demasiado fácil hacer polimorfirsmo en Java y se quedan con la idea de "Que!! eso es todo?!" pues les diré que sí, eso es todo.

Lo interesante aquí viene en la forma en la que se utiliza el polimorfismo y porque es tan importante en la POO.

Por ejemplo en los plugins se escribe código y se llaman métodos sobre clases que ni siquiera existen aún, porque será el autor del plugin el que provea esa nueva funcionalidad.

De la misma forma, la gran mayoría de los famosos patrones de diseño se basan precisamente en esto, en el polimorfismo para que sean las implementaciones las que digan que es lo que se va a hacer.

Y en el ejemplo mismo que es tan burdo, se puede agregar fácilmente quizá un año después de haber escrito este pedazo de código, un nuevo "Guardador" que utilice la red en vez de la base de datos o el sistema de archivos, bastaría definir el nuevo método:

class GuardaEnRed extends Guardador  {
   void salva( Persona persona ) {
       Socket s = new Socket( someServer, somePort );
       DataOutputStream dos = new  DataOutputStream( s.getOutputStream() );
       dos.writeUTF( persona.nombre() );
       dos.writeUTF( persona.apellido() );
       dos.close();
    }
}



Comentarios

Publicar un comentario