0% encontró este documento útil (0 votos)
55 vistas6 páginas

Herencia y Polimorfismo

Descargar como pdf o txt
Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1/ 6

Herencia y PolimorfIsmo en JAVA

La herencia es la transferencia de bienes que pasan de ser de los padres a sus hijos. Lo
mismo funciona con java. 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 llamará subclase y la clase que ya teníamos se
llamará 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.

Sobreescritura de variables y métodos. Una clase que extiende a otra puede declarar
atributos con el mismo nombre que algún atributo de la clase a la que extiende, se dice que
el atributo se ha sobrescrito u ocultado. Un uso de sobre escritura de atributos es la
extensión del tipo.
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
Las adaptaciones son dependientes del lenguaje

Clases abstractas. Un método se puede declarar como abstract. El método así declarado
puede no implementar nada. Si una clase contiene uno o más métodos declarados como
abstract, ella a su vez debe ser declarada como abstract. No se pueden crear instancias de
una clase declarada como abstract. Las clases que la extiendan deben obligatoriamente
sobrescribir los métodos declarados como abstract.
Las clases abstract funcionan como plantillas para la creación de otras clases.

Interfaces

La interface es la generalización de las clases abstractas. Si queremos que una determinada


clase vaya a tener cierto comportamiento, hacemos que implemente una determinada
interface. En la interface no se implementa el comportamiento, únicamente se especifica
cual va a ser, es decir, se declaran los métodos, pero no se implementan. No se pueden
crear instancias de una interface. Siguiendo con nuestro ejemplo de la clase Punto, hasta
ahora con ella sólo podemos representar puntos matemáticos, esos puntos no se pueden
dibujar. Si deseamos que posean la característica de poderse dibujar lo indicamos a través
de una interface
interface sePuedeDibujar {

static final Color rojo = Color.RED;


void dibujate();
void ponColor(Color unColor);
Color dameColor();

Todos los métodos declarados en una interface son públicos, así como sus atributos y la
misma interface. Una referencia a una interface puede referenciar a cualquier instancia de
clase que implemente dicho interface.
Finalmente, una interface puede extender u otra interface. Y si una clase extiende esta
interface, debe implementar todos los métodos definidos en toda la interface

Paquetes:
Los paquetes sirven para organizar jerarquicamente las clases. Para declarar que una clase
pertenece a un paquete basta incluir la sentencia package ejemplo.nombre.paquete; en el
fichero de definición de la clase.

El fichero de clase resultado de la compilación se debe colocar dentro de algún directorio


que pertenezca al calsspath y bajo la estructura de directorios ejemplo/nombre/paquete. Al
estructurar de este modo las clases, estamos estableciendo un dominio de nombres que la
máquina virtual de Java utiliza, por ejemplo, cuando nuestra aplicación utiliza clases
distribuidas en una red de computadores. Es recomendable que las clases que estan
lógicamente realacionadas pertenezcan al mismo paquete. Por ejemplo, al inicio de los
ficheros de definición Punto.java y Punto3D.java debemos incluir package
matematicas.geometria; Todas las clases dentro de un mismo paquete tienen acceso al
resto de clases declaradas como públicas. Como ya sabes, para poder acceder a una clase de
otro paquete se ha de importar este mediante la sentencia import.

En un lenguaje con sistema de tipos dinámico todas las variables son potencialmente
polimórficas.
En un lenguaje con sistema de tipos estático la variable polimórfica es la materialización del
principio de sustitución.
En Java: las referencias a objetos.
En C++: punteros o referencias a clases polimórficas
El polimorfismo en Java se refiere a que un objeto puede tomar diferentes formas de
comportarse, es decir, que las subclases de una clase pueden definir su propio
comportamiento. El polimorfismo hace posible que un usuario pueda añadir nuevas clases a
una jerarquía sin modificar o recompilar el código escrito en términos de la clase base.
Permite programar a nivel de clase base utilizando objetos de clases derivadas
(posiblemente no definidas aún): Técnica base de las librerías/frameworks (UD8)
Aun así, compartir comportamiento de su clase padre. Como se puede ver, la herencia y el
polimorfismo en java van muy ligados.
Así que será necesario tener bien claro este concepto para poder entender el polimorfismo.

La diferencia entre herencia y polimorfismo es que herencia está relacionada con clases y
polimorfismo con métodos.

Existen 4 tipos de polimorfismo:


- Sobrecarga
Es cuando existen funciones con el mismo nombre, con funcionalidad similar; en clases que
son completamente independientes una de la otra. 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()

- Paramétrico:

Existen funciones con el mismo nombre, pero se usan diferentes parámetros (nombre o
tipo). Se selecciona el método dependiendo del tipo de datos que se mande.
- Variables polimórficas:
(Polimorfismo de asignación) Variable que se declara con un tipo pero que referencia en
realidad un valor de un tipo distinto (normalmente relacionado mediante herencia). Una
variable polimórfica es aquélla que puede referenciar más de un tipo de objeto. Puede
mantener valores de distintos tipos en distintos momentos de ejecución del programa.
- Inclusión:
Es cuando se puede llamar a un método sin tener que conocer su tipo, así no se toma en
cuenta los detalles de las clases especializadas, utilizando una interfaz común
Estas heredan del mismo padre, cada clase sobrescribirá un método del padre para ver
cómo se comporta el polimorfismo.
Genericidad: Propiedad que permite definir una clase o una función sin tener que
especificar el tipo de todos o algunos de sus miembros o argumentos. Su utilidad principal
es la de agrupar variables cuyo tipo base no está predeterminado (p. ej., listas, colas, pilas
etc. de objetos genéricos: Java Collection Framework). Es el usuario el que indica el tipo de
la variable cuando crea un objeto de esa clase. En C++ esta característica apareció a finales
de los 80. En Java, existe desde la versión 1.5.
Dos tipos de genéricos:
Métodos genéricos: son útiles para implementar funciones que aceptan argumentos de tipo
arbitrario.
Clases genéricas: su utilidad principal consiste en agrupar variables cuyo tipo no está
predeterminado (clases contenedoras). El problema con la genericidad es que sólo podemos
utilizar aquellos métodos que estén definidos en Object. La genericidad restringida permite indicar
que los tipos genéricos pertenezcan a una determinada jerarquía de herencia. Esto permite utilizar la
interfaz de la clase usada como raíz de la jerarquía en los métodos/clases genéricos.

Dos tipos de sobrecarga:

Basada en ámbito: Métodos con diferentes ámbitos de definición, independientemente de sus


signaturas de tipo. Por ejemplo, método toString() en Java. Métodos con diferentes ámbitos de
definición, independientemente de sus signaturas de tipo. Permitido en todos los lenguajes OO. Un
mismo método puede ser utilizado en dos o más clases. Por ejemplo, Sobrecarga de operadores
como funciones miembro. Distintos ámbitos implican que el mismo nombre de método puede
aparecer en ellos sin ambigüedad ni pérdida de precisión. La sobrecarga por ámbito no requiere que
las funciones asociadas con un nombre sobrecargado tengan ninguna similitud semántica, ni la
misma signatura de tipo.

Basada en signatura: Métodos con diferentes signaturas de tipo en el mismo ámbito de definición.
Métodos con diferentes signaturas de tipo en el mismo ámbito de definición. No permitido en todos
los lenguajes OO. Por ejemplo, Cualquier conjunto de funciones no miembro (en el ámbito de
definición global) que comparten nombre. Dos o más métodos en la misma clase pueden tener el
mismo nombre siempre que tengan distinta signatura de tipos

Métodos en el mismo ámbito pueden compartir el mismo nombre siempre que difieran en número,
orden y, en lenguajes con tipado estático, el tipo de los argumentos que requieren. Este estilo ocurre
en muchos lenguajes funcionales, en algunos imperativos (e.g. ADA) y en lenguajes OO como C++,
C#, Java, Delphi Pascal o CLOS

C++ permite esta sobrecarga de manera implícita siempre que la selección del método requerido por
el usuario pueda establecerse de manera no ambigua en tiempo de compilación. Esto implica que la
signatura no puede distinguirse sólo por el tipo de retorno

Con las funciones virtual y el polimorfismo es posible diseñar e implementar sistemas que sean más
fácilmente extensibles. Es posible escribir programas para que procesen objetos de tipos que tal vez
no existan cuando el programa está bajo desarrollo.La programación polimórfica con funciones
virtual puede eliminar la necesidad de lógica de switch. El programador puede utilizar el mecanismo
de función virtual para realizar automáticamente la lógica equivalente, evitando de esta forma los
tipos de errores asociados con la lógica de switch. El código cliente que toma decisiones acerca de
tipos de objetos y representaciones es señal de un pobre diseño de clases. Las clases derivadas
pueden proporcionar su propia implementación de una función virtual de clase base, en caso de ser
necesario, pero si no lo hacen se utiliza la implementación de la clase base. Si se invoca una función
virtual haciendo referencia a un objeto específico por nombre y utilizando el operador punto de
selección de miembros, la referencia se resuelve en tiempo de compilación (a esto se le llama enlace
estático), y la función virtual que se llama es aquélla definida para (o heredada por) la clase de ese
objeto particular Hay muchas situaciones en las cuales es útil definir clases para las cuales el
programador nunca pretende instanciar ningún objeto. A tales clases se les llama clases abstractas.
Debido a que sólo se utilizan como clases base, normalmente las mencionaremos como clases base
abstractas. No es posible instanciar en un programa ningún objeto de una clase abstracta. Las clases
de las que se pueden instanciar objetos son llamadas clases concretas. Una clase se hace abstracta
mediante la declaración de que una o más de sus funciones virtual sean puras. Una función virtual
pura es aquélla que tiene un inicializador de = 0 en su declaración. Si una clase se deriva de una clase
que tiene funciones virtual puras sin proporcionar una definición para esa función virtual pura en la
clase derivada, dicha función sigue siendo pura en la clase derivada. Por consecuencia, la clase
derivada también es una clase abstracta (y no puede tener ningún objeto). El polimorfismo se
implementa por medio de funciones virtual. Cuando se hace una petición, por medio de un
apuntador o referencia a clase base, para que se utilice una función virtual, C++ elige la función
sobrepuesta correcta en la clase derivada adecuada que está asociada con el objeto. Mediante el
uso de funciones virtual y el polimorfismo una llamada de función miembro puede causar diferentes
acciones, dependiendo del tipo del objeto que recibe la llamada. Aunque no podemos instanciar
objetos de clases base abstractas, sí podemos declarar apuntadores hacia clases base abstractas.
Tales apuntadores pueden utilizarse para permitir manejos polimórficos de objetos de clases
derivadas cuando tales objetos se instancian a partir de clases concretas. Regularmente se agregan
nuevos tipos de clases a los sistemas. Las nuevas clases son amoldadas mediante el enlace dinámico
(también llamado enlace tardío). No es necesario saber el tipo de un objeto en tiempo de
compilación para que se pueda compilar una llamada de función virtual. En tiempo de ejecución la
llamada de función virtual se hace coincidir con la función miembro del objeto que la recibe. El
enlace dinámico permite que los ISV distribuyan software sin revelar sus secretos propios. Las
distribuciones de software pueden consistir solamente de archivos de encabezado y archivos objeto.
No es necesario revelar nada del código fuente. Los desarrolladores de software después pueden
utilizar la herencia para derivar nuevas clases a partir de las que proporcionan los ISV. El software
que funciona con las clases que proporcionan los ISV continuará funcionando con las clases
derivadas y utilizará (por medio de enlace dinámico) las funciones virtual sobrepuestas que se
proporcionan en esas clases. El enlace dinámico requiere que en tiempo de ejecución la llamada a
una función miembro virtual sea dirigida hacia la versión de la función virtual adecuada para esa
clase. Una tabla de funciones virtuales, llamada vtable, está implementada como un arreglo que
contiene apuntadores de función. Cada clase que contiene funciones virtual tiene una vtable. Para
cada función virtual de la clase, la vtable tiene una entrada que contiene un apuntador a función
hacia la versión de la función virtual que hay que utilizar para un objeto de esa clase. La función
virtual que hay que utilizar para una clase particular podría ser la función definida en esa clase, o una
función heredada directa o indirectamente de una clase base que está en un nivel más elevado en la
jerarquía. Cuando una clase base proporciona una función miembro virtual, las clases derivadas
pueden sobreponer a la función virtual pero no están obligadas a hacerlo. Por lo tanto, una clase
derivada puede utilizar la versión de la clase base de la función miembro virtual, y esto estaría
indicado en la vtable. Cada objeto de una clase que tiene funciones virtual contiene un apuntador
hacia la vtable de esa clase. El apuntador a función adecuado en la vtable se obtiene y desreferencia
para completar la llamada en tiempo de ejecución. Esta búsqueda en la vtable y la desreferenciación
del apuntador requieren una sobrecarga ínfima del tiempo de ejecución, que por lo general es
menor que el mejor código cliente posible. Declare como virtual al destructor de la clase base si la
clase contiene funciones virtual. Esto hace que todos los destructores de las clases derivadas sean
virtual aunque no tengan el mismo nombre que el destructor de la clase base. Si un objeto de la
jerarquía es destruido explícitamente por medio de la aplicación del operador delete al apuntador
de clase base a un objeto de clase derivada, se invoca el destructor de la clase adecuada. Cualquier
clase que tenga uno o más apuntadores 0 en su vtable es una clase abstracta. Las clases que no
tengan un apuntador a vtable que sea 0 (como Point, Circle y Cylinder) son clases concretas.

También podría gustarte