Resumen OCP(SCJP): Capítulo 2. Orientación a Objetos

por | junio 26, 2013

POLIMORFISMO (OBJETIVO 5.2):

  • Una variable de referencia es siempre (e inalterable) de un solo tipo, pero puede referirse a un subtipo de objeto.
  • El tipo de la variable de referencia (no el tipo del objeto), determina cuales pueden ser los métodos invocados.
  • Las invocaciones a métodos polimórficos se realizan solo a los métodos de instancia sobreescritos

SOBREESCRITURA Y SOBRECARGA (OBJETIVO 1.5 Y 5.4):

Con respecto al método el método sobreescrito(Override):

  • Debe poseer el mismo tipo de retorno, excepto a partir de Java 5, en donde el tipo de retorno puede ser una subclase (a esto se lo denomina como retorno covariante).
  • No debe poseer un modificador de acceso más restrictivo.
  • Puede poseer un modificador de acceso menos restrictivo.
  • No debe lanzar nuevas o mayores (en relación al árbol de herencia) excepciones comprobadas.
  • Puede lanzar menos o menores (en relación al árbol de herencia) excepciones comprobadas, o cualquier excepción no comprobada

Con respecto al método que sobrecargado:

  • Pueden poseer diferentes tipos de retorno, si las listas de argumentos son diferentes.
  • Pueden poseer diferentes modificadores de acceso.
  • Pueden lanzar diferentes excepciones.

Ejemplos ilegales de Métodos Override(ninguno compila)

public class Animal{
    public void eat(){ }
}
Código de Sustitución Ilegal Problema con el código
private void eat(){ } El modificador de acceso es mas restrictivo
public void eat() throws IOException { } Declara una excepción marcada que no está definida en al versión de la superclase
public void eat(String food){ } Una sobrecarga legal pero no un override porque la lista de argumentos ha cambiado
public String eat() { } No es un override porque el tipo de retorno es diferente. No es una sobrecarga tampoco porque no ha cambiado la lista de argumentos
  • Los métodos pueden ser sobreescritos o sobrecargados; los constructores pueden ser sobrecargados pero no sobreescritos.
  • El polimorfismo se encuentra en la sobreescritura, no en la sobrecarga.
  • El tipo de un objeto (no el tipo de la variable de referencia), determina que método sobreescrito es utilizado en tiempo de ejecución.
  • El tipo de la referencia determina que método sobrecargado se utilizará en tiempo de complicación.

Para resumir, cuando se trata de la llamada a un método sobreescrito, este  es decidido en tiempo de ejecución basándose en el tipo de objeto, pero la versión sobrecargada del método a llamar está basado en el tipo de referencia del argumento pasado en tiempo de compilación.

POLIMORFISMO EN MÉTODOS SOBRECARGADOS Y SUSTITUIDOS

A veces, un método está sobrecargado y sustituido. Imagina una clase Animal y una clase Horse que son así:

class Animal{
    public void eat(){
        System.out.println("Animal genérico comiendo");
    }
}

public class Horse extends Animal{
    public void eat(){
        System.out.println("Horse comiendo paja");
    }

    public void eat(String s){
        System.out.println("Hose comiendo "; + s);
    }
}
Código de Invocación del método Resultado
Animal a = new Animal() a.eat() Animal genérico comiendo
Horse h = new Horse() h.eat() Horse comiendo paja
Animal ah = new Horse() ah.eat() Horse comiendo paja. Polimorficamente funciona. El tipo de objeto (Horse) no el tipo de referencia (Animal) es usado para determinar que método eat() se llama.
Horse he = new Horse() he.eat(“Manzanas”) Horse comiendo Manzanas El método sobrecargado eat(String s) es invocado
Animal a2 = new Animal() a2.eat(“Treats”) Error de compilación. El compilador ve que la clase Animal no tiene un método eat() que coja un String.
Animal ah2 = new Horse() ah2.eat(“Carrots”) Error de Compilación. El compilador se mantiene mirando solo la referencia y ve que Animal no tiene ningún método eat() que coja un String.
Método Sobrecargado(Overload) Método Sustituido(Override)
Argumentos Deben cambiar No deben cambiar
Tipo de retorno Puede cambiar No puede cambiar excepto retorno covariante
Excepciones Puede cambiar Puede reducir o eliminar.
No puede ser lanzada ninguna nueva o mas amplia
Acceso Puede cambiar No debe hacerlo mas restrictivo
(Pero si ser menos restrictivo)
Invocación El tipo de referencia determina cual versión
sobrecargada es seleccionada.
Ocurre en tiempo de compilación.
El tipo de objeto determina cual
de los métodos es llamado

CONVERSIÓN DE VARIABLES DE REFERENCIA (OBJETIVO 5.2):

  • Existen dos tipos de conversión de variables de referencia: especificación (downcasting) y generalización (upcasting).
  • Downcasting: Con una referencia a un supertipo de objeto, se puede realizar una conversión explícita a un subtipo, para acceder a los miembros de ese subtipo.
  • Upcasting: Con una referencia a un subtipo de objeto, se puede acceder explícita o implícitamente a los miembros de la clase base.
class Animal{ }
class Dog extends Animal { }
class DogTest{
    public static void main(String[] args){
        //upcasting
        Dog d = new Dog();
        Animal a1 = d;  // Upcast implícito
        Animal a2 = (Animal) d;  // o también explícito

        //downcasting
        Animal animal = new Dog();
        Dog d1 = (Dog) animal; // cast solo explícito
    }
}

TIPOS DE RETORNO (OBJETIVO 1.5):

  • Los métodos con referencias a objetos como tipo de retorno, pueden devolver subtipos.
    Los métodos con una interface como tipo de retorno, pueden devolver cualquier instancia de una clase que la implemente.
class Alpha{
    Alpha doStuff(char c){
        return new Alpha();
    }
}

class Beta extends Alpha{
    Beta doStuff (char c){  //Sustitucion legal en Java 1.5
        return new Beta();
    }
}

En un método con un tipo de retorno primitivo, podemos retornar cualquier valor o variable que pueda ser implícitamente convertida al tipo de retorno declarado.

public int foo(){
    char c = 'c';
    return c; // char es compatible con int
}

En un método con un tipo de retorno primitivo, podemos retornar cualquier valor o variable a la que pueda hacerse cast al tipo de retorno declarado.

public int foo(){
    float f = 32.5f;
    return (int) f;
}

CONSTRUCTORES E INSTANCIACIÓN (OBJETIVO 1.6 Y 5.4):

  • Los constructores pueden utilizar cualquier modificador de acceso.
  • La primera línea de todos los constructores debe ser this() (si es un constructor sobrecargado) o super().
  • Si una superclase no posee un constructor sin argumentos, es aconsejable crear un constructor sin argumentos el cuál invoque a alguno de los constructores existentes pasando parámetros por defecto.
  • Los constructores nunca son heredados, y por lo tanto no pueden ser sobreescritos.
  • Las invocaciones a this() y super() no pueden estar en un mismo constructor. Se puede tener uno u otro, pero nunca ambos.

ESTÁTICOS (OBJETIVO 1.3):

  • Los métodos estáticos son utilizados para implementar comportamientos que no están afectados por el estado de ninguna instancia.
  • Un método estático no puede acceder a una variable de instancia directamente.
  • Los métodos estáticos no pueden ser sobreescritos, pero si pueden ser redefinidos.
class Animal {
	static void doStuff() {
		System.out.print("a ");
	}
}

class Dog extends Animal {
	static void doStuff() { // se está redifiniendo,
		// NO override
		System.out.print("d ");
	}

	public static void main(String[] args) {
		Animal[] a = { new Animal(), new Dog(), new Animal() };
		for (int x = 0; x < a.length; x++)
			a[x].doStuff(); // invocando al metodo estatico
	}
}

Salida del programa
a a a

ACOPLAMIENTO Y COHESIÓN (OBJETIVO 5.1):

  • El acoplamiento se refiere al grado en que una clase conoce o usa los miembros de otra clase.
  • Débil acoplamiento es el estado deseado para tener clases que estén bien encapsuladas, minimizadas las referencias entre ellas, y se limitan al uso de las API?s.
  • Fuerte acoplamiento es el estado indeseado de tener clases que no respetan las reglas de bajo acoplamiento.
  • La cohesión se refiere al grado en que una clase, cumple un rol bien definido o tiene una responsabilidad específica.
    Alta cohesión es el estado deseado de una clase que posee un rol bien definido.
  • Baja cohesión es el estado indeseado de una clase que posee muchos roles y demasiadas responsabilidades.

EOF