La reutilización
de código se refiere al comportamiento y a las técnicas que garantizan
que una parte o la totalidad de un programa informático existente se pueda
emplear en la construcción de otro programa. De esta forma se aprovecha el
trabajo anterior, se economiza tiempo, y se reduce la redundancia.
La
manera más fácil de reutilizar código es copiarlo total o parcialmente desde el
programa antiguo al programa en desarrollo. Pero es trabajoso mantener
múltiples copias del mismo código, por lo que en general se elimina la
redundancia dejando el código reusable en un único lugar, y llamándolo desde
los diferentes programas. Este proceso se conoce como abstracción. La abstracción puede verse
claramente en lasbibliotecas de
software, en las que se
agrupan varias operaciones comunes a cierto dominio para facilitar el
desarrollo de programas nuevos. Hay bibliotecas para convertir información
entre diferentes formatos conocidos, acceder a dispositivos de almacenamiento
externos, proporcionar una interfaz con otros programas, manipular información
de manera conocida (como números, fechas, o cadenas de texto).
Para
que el código existente se pueda reutilizar, debe definir alguna forma de
comunicación o interfaz. Esto se puede dar por llamadas a una subrutina, a un
objeto, o a una clase.
Como se ha comentado anteriormente la
clase descendiente puede añadir sus propios atributos y métodos pero también
puede sustituir u ocultar los heredados. En concreto:
1. Se puede declarar un nuevo atributo con
el mismo identificador que uno heredado, quedando este atributo oculto.
Esta técnica no es recomendable.
2. Se puede declarar un nuevo método
de instancia con la misma cabecera que el de la clase ascendiente, lo
que supone su sobreescritura. Por lo tanto, la sobreescritura o
redefinición consiste en que métodos adicionales declarados en la clase
descendiente con el mismo nombre, tipo de dato devuelto y número y tipo de
parámetros sustituyen a los heredados.
3. Se puede declarar un nuevo método
de clase con la misma cabecera que el de la clase ascendiente, lo que
hace que éste quede oculto. Por lo tanto, los métodos de clase o
estáticos (declarados como static) no pueden ser redefinidos.
4. Un método declarado con el
modificador final tampoco puede ser redefinido por una clase derivada.
5. Se puede declarar un constructor de
la subclase que llame al de la superclase de forma implícita o de mediante la
palabra reservada super.
6. En general puede accederse a los
métodos de la clase ascendiente que han sido redefinidos empleando la palabra
reservada super delante del identificador del método. Este mecanismo sólo
permite acceder al metodo perteneciente a la clase en el nivel inmediatamente
superior de la jerarquía de clases.
Construyamos
la clase Taxista.java con el siguiente código:
public class Taxista extends Persona {
private int nLicencia;
public void setNLicencia(int num){
nLicencia = num;
}
public int getLicencia(){
return nLicencia;
}
}
Y
construyamos ArranqueTaxista.java:
public class ArranqueTaxista {
public static void main (String arg[]){
Taxista
tax1 = new Taxista();
tax1.setNombre("Luis");
tax1.setEdad(50);
System.out.println( tax1.getNombre());
System.out.println(tax1.getEdad());
}
}
Ahora
intentemos usar el constructor que existía en la clase Persona que recibia el
nombre de la persona y vamos a usarlo para la clase Taxista. Para ello
construyamos la clase ArranqueTaxista2.java:
public class ArranqueTaxista2 {
public static void main (String arg[]){
Taxista
tax1 = new Taxista("Jose");
tax1.setEdad(50);
System.out.println( tax1.getNombre());
System.out.println(tax1.getEdad());
System.out.println(tax1.getNLicencia());
}
}
Se
genera un error de compilación, debido a que los constructores no se heredan,
sino que hay que definir nuestros propios constructores. Agreguemos en la clase
Taxista los siguientes constructores:
public
Taxista(int licencia){
super();
nLicencia
= licencia;
}
public Taxista(String nombre,int
licencia){
super(nombre);
nLicencia
= licencia;
}
Ahora
si podremos compilar y ejecutar la clase ArranqueTaxista2. La llamada al método
super indica que estamos llamando a un constructor de la clase base (pensemos
que un Taxista antes que Taxista es Persona y por tanto tiene sentido llamar al
constructor de Persona antes que al de Taxista). Además gracias al número de
parámetros de la llamada a super podemos especificar cuál de los constructores
de la clase base queremos llamar.
En
java se pueden emplear dos palabras clave: this y super. Como vimos en la
unidad 1, this hace alusión a todo el objeto y super hace alusión a la parte
heredada, por ello empleamos super para referenciar al constructor de la clase
base.
Ahora
vamos a agregar la función getNombre dentro de la clase Taxista, es decir,
tenemos la misma función en Persona y en Taxista:
public
String getNombre() {
return
"Soy un taxista y me llamo: " + super.getNombre();
}
Compilamos
Taxista y ejecutamos ArranqueTaxista2. Veremos que el mensaje que aparece en
pantalla demuestra que la función getNombre llamada es la de del tipo real del
objeto construido, en este caso la de la clase derivada que es Taxista.
Tambien
apreciamos que para acceder al atributo nombre es necesario acceder al método
getNombre de la clase base (y por ello emplear super).
En
java los atributos y métodos de la clase base pueden cambiar su modificador de
visibilidad dentro de la clase derivada, la siguiente tabla recoge dichos
cambios:
Modificadores
en la clase base:
public
private
protected
paquete
En
la clase derivada se transforman en:
public
inaccesible
protected
paquete
Inaccesible
significa que, a pesar de haber sido heredado, no hay permisos en la clase
derivada para poder acceder a dicho elemento inaccesible, pero aún así, se
pueden llamar a métodos de la clase base que si pueden acceder y modificar al
elemento.
Recordemos
que protected significa que es private, pero que al heredar no se hace
inaccesible, es decir que desde la clase derivada se puede acceder.
No hay comentarios:
Publicar un comentario