Sei sulla pagina 1di 11

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin

Herencia
INTRODUCCIN
La herencia es un concepto asociado a la programacin orientada a objetos (POO) que nos permite establecer relaciones de tipo entre ciertos elementos, permitindonos extender (heredar y/o especializar) su comportamiento. El objetivo primordial de la herencia es permitir la creacin de una clase a partir de otra para as permitir la reutilizacin de cdigo. Teniendo esto, en este documento se explora el concepto de herencia para luego ilustrar sus caractersticas especficas para el lenguaje Java.

CONCEPTO DE HERENCIA
Conceptualmente, la herencia proviene de la dimensin de razonamiento de la variedad, es decir, permite clasificar un elemento de acuerdo a su tipo (de acuerdo a qu es) estableciendo una generalizacin y permitiendo construir jerarquas (Figura 10.1).

Figura 10.1: Jerarquas y generalizacin. Si se toma como ejemplo la jerarqua presentada en la figura 10.1, es posible observar la relacin de generalizacin existente entre, por ejemplo, las entidades Animal, Vertebrado y Mono. Podemos observar por generalizacin que es posible establecer que Mono es un Vertebrado (Mono es un tipo de Vertebrado). A su vez, Vertebrado es un Animal (Vertebrado es un tipo de Animal) y por transitividad determinar finalmente que Mono es un Animal.

1 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin Formalmente, las relaciones de generalizacin establecen jerarquas (orden que permite establecer la importancia/peso/categora de un elemento con respecto a otro). Es posible ver la jerarqua desde el punto de vista de la transitividad, ya que si bien es posible establecer que Mono es un Animal (el caso especfico Mono es representado por un caso ms general Animal) no es posible afirmar que Animal es un Mono (ya que Animal es un caso general, por ende, Mono es un subconjunto de Animal).

Figura 10.2: Jerarquas y generalizaciones como conjuntos. Teniendo estos conceptos, se abordar la herencia desde el punto de vista de Java con el objetivo de conocer como el lenguaje implementa esta caracterstica. Cabe notar que la herencia es un concepto asociado a la programacin orientada a objetos (POO), por ende, ste aplica a cualquier lenguaje orientado a objetos y su implementacin y caractersticas pueden diferir lenguaje a lenguaje.

2 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin

HERENCIA EN JAVA
El objetivo primordial de la herencia, desde el punto de vista del programador, es la reutilizacin de cdigo. Para lograr este objetivo, Java permite que una clase (subclase, clase hijo) pueda heredar (es decir, obtener) el comportamiento de otra clase (superclase o clase padre) para luego tener la opcin de especializar dicho comportamiento. Este comportamiento heredable tiene que ver con los miembros de la superclase (esto es, atributos y mtodos), por lo cual influye directamente los modos de acceso de cada uno de dichos miembros. La tabla 10.1 ilustra esta relacin, estableciendo cuales son las posibilidades de herencia para cada uno de los modos de acceso existentes en el lenguaje. Tabla 10.1: Modos de acceso y herencia. Modo de acceso Pblico Modificador public Heredable? SI, por cualquier subclase en cualquier paquete. SI, por cualquier subclase en cualquier paquete. NO, en ningn caso.

Protegido

protected

Privado

private

Por defecto

Sin modificador

SI, por cualquier subclase EN EL MISMO paquete.

De la tabla 10.1 es posible observar que la restriccin ms dura corresponde al modo de acceso privado (modificador private) y las ms blandas corresponden al modo de acceso pblico y protegido (public y protected). Cabe notar que si bien desde el punto de vista de la herencia pblico y protegido poseen el mismo significado, desde el punto de vista de la visibilidad protegido es ms restrictivo que pblico. Teniendo claro las posibilidades de herencia de acuerdo al modo de acceso, Java permite heredar miembros (atributos y mtodos) a travs de 2 mecanismos: 1. Herencia simple (Extensin, extends). 2. Implementacin (Implementar, implements).

3 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin Cabe notar que si bien la implementacin tcnicamente no corresponde a la herencia de caractersticas, si se relaciona con la especializacin y por ende es tratado en esta seccin como herencia (y en la literatura en general). Herencia simple La herencia simple puede ser vista desde dos puntos de vista: La creacin de superclases abstractas y la creacin de superclases concretas. Como concepto, se puede definir que cualquier clase que no sea abstracta (que no contenga el modificador abstract) es una clase concreta. Cabe notar que antes de continuar es necesario establecer que si bien conceptualmente es correcto que una clase puede ser hija (heredar de, ser subclase de) ms de una clase, el lenguaje Java no permite la herencia mltiple, es decir, una clase puede heredar de (ser hija de, ser subclase de) una sola clase, no de mltiples. Para heredar atributos y/o mtodos desde clases concretas, se tomar como ejemplo las clases definidas en la figura 10.3.

Figura 10.3: Ejemplo de herencia simple en clases concretas. Como se puede observar, la herencia se activa utilizando la palabra reservada extends. Esta palabra reservada permite establecer que Vertebrado es un tipo de Animal (Vertebrado es un Animal), por ende, en este ejemplo la superclase sera Animal y la subclase Vertebrado. El hecho de establecer esta relacin implicar que la clase Vertebrado heredar el mtodo hacerRuido() (ya que puede dado que es pblico) y permitir a cada objeto (instancia) de tipo Vertebrado utilizarlo tal y como si estuviese definido dentro de la clase Vertebrado, haciendo la sentencia presentada en la figura 10.4 vlida para el compilador.

4 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin

Figura 10.4: Sentencia vlida para cada objeto de tipo Vertebrado. El beneficio que se puede observar en este tipo de herencia simple corresponde al de la centralizacin. Si se observa, cada clase que se establezca como hijo de la clase Animal (en este caso, Vertebrado) heredar el comportamiento de la misma (en este caso, hacerRuido()), lo cual permitir que cualquier cambio futuro al funcionamiento de este mtodo se haga slo en la clase Animal, sin afectar a cualquiera de sus subtipos (o subclases), entregndole a cada subclase un comportamiento general predefinido (generalizacin). Junto con la generalizacin, a travs de cada subclase es posible obtener el beneficio de la especializacin. Desde el punto de vista de Java, especializar un mtodo heredado corresponde a sobrescribirlo (override), lo cual es posible observar en la figura 10.5.

Figura 10.5: Especializacin del mtodo hacerRuido(). Conceptualmente, es posible afirmar que si bien cada Animal puede hacer ruido, es vlido decir que el ruido que realiza cada tipo de Animal es especfico a l, luego, cada subclase

5 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin tiene permitido especificar el comportamiento heredado. Para especificar comportamiento heredado (es decir, sobrescribir un mtodo), debemos observar que: el

1. Utilizaremos la anotacin @Override antes de la declaracin del mtodo para indicar al compilador que este mtodo ya se encuentra definido en la superclase y que deseamos especializarlo. NO ES OBLIGATORIO, pero si correcto hacerlo. 2. Al indicar que se desea sobrescribir, es necesario que el mtodo que sobrescribe (la especializacin) tenga la misma firma que el mtodo que se desea sobrescribir (el general de la superclase). Esto implica que: a. El modo de acceso del mtodo especializado debe ser igual o menos restrictivo (si en la superclase es protected, puede ser sobrescrito como protected o public, pero private no). b. La lista de argumentos de ambos mtodos (el general y el especfico) debe ser EXACTAMENTE LA MISMA. c. El tipo de retorno del mtodo especfico puede ser el mismo que el del general o un subtipo de este. Especial cuidado con los tipos numricos, ya que si bien es posible convertir int en double, no es vlido decir que int es un SUBTIPO DE double. d. Existe otro conjunto de reglas asociados a la sobrescritura con relacin al manejo y declaracin de excepciones, las cuales no sern tratadas en este documento. Para continuar la visin de la herencia simple, se debe introducir el concepto de clase abstracta. Una clase se considera abstracta si en su definicin (declaracin) incluye el modificador abstract. Conceptualmente, una clase abstracta representa un elemento que si bien puede definir un funcionamiento, puede adems declarar que posee cierto comportamiento sin tener la necesidad de definirlo, obligando a sus subclases a hacerlo. Un ejemplo de clase abstracta puede ser visto en la figura 10.6.

6 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin

Figura 10.6: Ejemplo de clase abstracta. Al declarar una clase como abstracta, se le permite a dicha clase especificar la existencia de un mtodo abstracto, permitiendo a ese mtodo omitir su implementacin (el cdigo de su funcionamiento) y OBLIGANDO a sus subclases a especificar esa implementacin. Luego, podemos notar que cualquier clase que se declare como subclase de una clase abstracta, DEBE proveer una implementacin para cada uno de los mtodos abstractos definidos en la superclase (si no lo hace, no compila). As, al definir clases abstractas, debemos considerar que: 1. Si una clase posee un mtodo abstracto (marcado como abstract), la clase DEBE ser marcada como abstract. 2. Una clase abstracta puede no definir mtodos abstractos, por consecuencia, una clase abstracta puede contener mtodos abstractos y concretos. 3. Los mtodos abstractos no pueden poseer una definicin, es decir, deben terminar en punto y coma (;) en vez de llaves ({}). a. public abstract void saludar(); es vlido, pero public abstract void saludar{} no es vlido. 4. Dado que los mtodos abstractos estn hechos para ser heredados, no pueden ser marcados como private. 5. Las clases abstractas no se pueden instanciar, es decir, no se pueden crear objetos derivados directamente desde una clase abstracta. a. En el ejemplo, Animal animal = new Animal(); no ser vlido, ya que la clase Animal es abstracta. La razn para esto es que una clase abstracta puede contener mtodos abstractos, por ende, una instancia de ella puede

7 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin llegar a contener mtodos que no poseen una definicin, lo cual no est permitido. Heredar comportamiento desde una clase abstracta puede poseer ciertas ventajas. Por ejemplo, permite establecer una suerte de contrato con sus subclases, en el cual el compilador valida y verifica que cada subclase de una clase abstracta est obligada a implementar los mtodos abstractos que dicha superclase define. Por otro lado, la clase abstracta puede adems definir mtodos concretos, por los cual se mantiene la propiedad asociada a la generalizacin de implementar comportamiento general en una superclase. Teniendo esto, es decisin del programador la manera de implementar la herencia simple (a travs de clases concretas, a travs de clases abstractas o mezclando ambas). Esta decisin se asocia generalmente al diseo y entendimiento conceptual del problema a resolver.

Herencia: Implementacin de interfaces Como se dijo, una de las principales ventajas de las clases abstractas es que obligan a subclases a definir un comportamiento, constituyendo una especie de contrato entre padre-hijo. El concepto relevante en una interfaz es el mismo: indicar el comportamiento que cada hijo de la interfaz est obligado a implementar. Conceptualmente, una interfaz no es una clase. Las interfaces estn hechas para representar un rol (una serie de acciones o papeles que un elemento puede representar en un problema) y no una entidad participante (como es en el caso de las clases). Sin embargo, es posible ilustrar una interfaz como una clase abstracta QUE SOLO PUEDE DEFINIR MTODOS ABSTRACTOS. Un ejemplo se presenta en la figura 10.7.

Figura 10.7: Ejemplo de interfaz.

8 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin Como se dijo, conceptualmente una interfaz representa un rol y no un tipo. Si se aplica esta nocin al ejemplo presentado (basado en la figura 10.1) es posible decir que dada la jerarqua presentada, el rol Carnvoro puede ser aplicado tanto a vertebrados como invertebrados. Se plante adems que una interfaz y una clase abstracta no son lo mismo. Esto ocurre ya que una interfaz, a diferencia de una clase abstracta, no puede definir mtodos concretos, solo puede definir mtodos abstractos. Las restricciones y propiedades asociadas a interfaces son las siguientes: 1. La definicin de interfaces se rige, a nivel de archivos, por las mismas reglas que aplican a la definicin de clases (paquetizacin, una interfaz pblica por archivo y el archivo debe tener el mismo nombre, etc). 2. Para construir una interfaz, se utiliza la palabra reservada interface. Si se quiere, se puede ver como remplazar la palabra class por la palabra interface. La forma en que una clase (concreta o abstracta) indica que es hijo de (implementa una) interfaz es a travs de la palabra reservada implements. Cuando una subclase (o clase implementadora en este caso) utiliza dicha palabra reservada en su definicin, declara que cumplir es contrato impuesto por cierta interfaz, entregando una implementacin para cada uno de los mtodos que define la interfaz. La nica forma de omitir esta regla es que la clase implementadora sea adems abstracta, lo cual permite a dicha clase no proveer una implementacin y delegar el trabajo a una subclase concreta. Sobre la implementacin (o el uso de la palabra reservada implements), se tiene que: 1. La palabra reservada implements SIEMPRE va despus de extends. a. Como en el ejemplo presentado en la figura 10.7, extends Animal implements Carnivoro es correcto, implements Carnivoro extends Animal no lo es. b. De esto se desprende el hecho de que una clase puede elegir extender otra (extender) y adems implementar una o ms interfaces. 2. Una clase puede elegir implementar ms de una interfaz. En este caso, las interfaces a implementar (sus nombres) se separan por coma. a. Si suponemos la existencia de la interfaz Herbivoro, entonces podemos decir que es correcto decir class Humano extends Animal implements Carnivoro, Herbivoro. Se debe notar que esta es una gran diferencia que tiene la implementacin con la extensin. 3. Una interfaz no puede implementar otra interfaz (lgico, no puede proveer funcionamiento para un mtodo si slo puede declarar mtodos abstractos). 4. Una interfaz si puede extender (ser hija de, heredar de, se subclase de) otra interfaz. 5. Una interfaz puede ser hija de (heredar de, ser subclase de, extender de) ms de una interfaz. 9 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin a. Si se supone la existencia de la interfaz Omnivoro, es vlido decir public interface Omnivoro extends Carnivoro, Herbivoro. Cabe notar que todas las observaciones anteriores son vlidas debido a que las interfaces son bsicamente contratos en los cuales no existen implementaciones (cdigo), solo declaraciones. Otra observacin curiosa sobre las interfaces se puede observar en las propiedades (modificadores asociados) de sus miembros (mtodos y atributos). Para estos, las reglas son las siguientes: 1. Todo atributo declarado en una interfaz es, por defecto, public static final. Esta distincin puede ser realizada de manera explcita (declarando dicho atributo como public static final) e implcita (no indicndolo). De cualquier manera, el compilador asumir que el atributo declarado es public static final y lo tratar como tal. a. Declaraciones implcitas incluyen declaraciones parciales, es decir, dado que todo atributo es por defecto public static final, las siguientes declaraciones de atributos son vlidas: i. public final int ATT = 1; ii. static final int ATT = 2; iii. final int ATT = 3; iv. int ATT = 4; b. Por consecuencia, todo atributo declarado dentro de una interfaz es siempre una CONSTANTE. 2. Todo mtodo declarado en una interfaz es, por defecto, public abstract. Esta definicin puede ser realizada tanto de manera explcita (declarando el mtodo como public abstract) como implcita (omitindolo). a. Declaraciones implcitas incluyen declaraciones parciales, es decir, dado que todo mtodo es por defecto public abstract, las siguientes declaraciones de mtodos son vlidas: i. public void mtodo(); ii. abstract void mtodo(); iii. void mtodo(); 3. Las condiciones implcitas no pueden ser contradichas por el programador. Es decir, no es posible indicar que un atributo en una interfaz es private siendo que por defecto es public static final. Luego, la figura 10.8 provee un ejemplo de las condiciones especificadas en este punto.

10 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Universidad de Santiago de Chile Facultad de Ingeniera Departamento de Ingeniera Informtica Mtodos de Programacin

Figura 10.8: Miembros de una interfaz.

11 Unidad 1: Paradigma de POO con lenguaje Java 2- 2013

Potrebbero piacerti anche