¿como dejar de heredar un método? y sobrescribiendo métodos.

Hola javamexico.org

me pregunto lo del título.

Supongamos que la Clase1 define el método public void heredable().

La Clase2 extiende a Clase1, hereda a heredable() y lo sobreescribe.

La Clase3 extiende a Clase2 y no quiero que esta herede el método heredable() ¿como se podría hacer?

---

Una solución que recuerdo haber leído es que la Clase2 no extienda a Clase1 sino que haga composición de Clase1, así que cuando clase3 extienda a Clase2 no herede nada de Clase1... pero ¿hay alguna forma "mas elegante" de hacerlo?

Ya había pensado al sobrescribir en Clase2 al método heredable() cambiarle el modificador de acceso a *private* pero según leí es prohibido cambiarle el modificador de acceso a otro mas restringido.

---

Por cierto, a los métodos heredados ¿que modificaciones se le pueden hacer al sobrescribirlos?

¿se pueden convertir en estáticos? un apunte es que los métodos static no se pueden sobrescribir
¿vale añadir la palabra clave "final" al sobrescribir para volverlo no-heredable?

Bueno, de los modificadores de acceso ya aclaré que se no se puede pasar de uno menos a mas restrictivo... pero entonces ¿cuales serian los niveles de conversión? ¿private -> protected -> nivelpaquete -> public ?

Sobre los parámetros leí que si se cambian el método heredado se oculta.

---

Entonces, las reglas de sobrescritura de métodos heredados seria de la siguiente forma?

[private->protected->(nivelpaquete)->public] [static] [final] [valorRetorno] nombreMetodo (parametros)

donde lo que está entre [...] están:

los que puede escribirse o no-escribirse como [los modificadores de acceso], [static] y [final]

y también están:

los que pueden ser cambiados por otras opciones [modificadores de acceso] y [valorRetorno]

Y que al realizar estos cambios todo sea "legal" y no estropeen la sobrescritura como cuando se cambian los parámetros?

Agradezco una ayuda y aclaración al respecto, un gran saludo.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Supongamos que la Clase1

Supongamos que la Clase1 define el método public void heredable().

La Clase2 extiende a Clase1, hereda a heredable() y lo sobreescribe.

La Clase3 extiende a Clase2 y no quiero que esta herede el método heredable() ¿como se podría hacer?

No puedes. Ese método forma parte de la "interfaz pública" de la clase y no puedes cambiarla

---

Una solución que recuerdo haber leído es que la Clase2 no extienda a Clase1 sino que haga composición de Clase1, así que cuando clase3 extienda a Clase2 no herede nada de Clase1... pero ¿hay alguna forma "mas elegante" de hacerlo?

Si, esta es una posibilidad y siempre es recomendable hacer un compuesto a heredar, por que la herencia es la forma más fuerte de acoplamiento que existe y este no siempre es deseable ( aunque no siempre es posible ) La desventaja que hay con esta forma, es que los objetos no son del mismo tipo, por lo que a la mezcla hay que añadir una interfaz con la palabra reservada "interface"

Ya había pensado al sobrescribir en Clase2 al método heredable() cambiarle el modificador de acceso a *private* pero según leí es prohibido cambiarle el modificador de acceso a otro mas restringido.

Es correcto, no puedes hacer más privada un metodo existente.

---

Por cierto, a los métodos heredados ¿que modificaciones se le pueden hacer al sobrescribirlos?

A su firma ( modificador de acceso, nombre, parametros etc ) solamente le puedes modificar la lista de excepciones que lanza quitándole existentes, no puedes ni siquiera hacer que lanze nuevas. A la forma en la que se comportan, todo.

¿se pueden convertir en estáticos? un apunte es que los métodos static no se pueden sobrescribir

No no se pueden volver estáticos

¿vale añadir la palabra clave "final" al sobrescribir para volverlo no-heredable?

Eso si, pero solo aplica para las subclases de tu subclase.

Bueno, de los modificadores de acceso ya aclaré que se no se puede pasar de uno menos a mas restrictivo... pero entonces ¿cuales serian los niveles de conversión? ¿private -> protected -> nivelpaquete -> public ?

casi, serían private->default(nivelpaquete)->protected->public

Sobre los parámetros leí que si se cambian el método heredado se oculta.

errh, como? Mmh no, no se oculta. Sigue estando ahí.

---

Entonces, las reglas de sobrescritura de métodos heredados seria de la siguiente forma?

[private->protected->(nivelpaquete)->public] [static] [final] [valorRetorno] nombreMetodo (parametros)

donde lo que está entre [...] están:

los que puede escribirse o no-escribirse como [los modificadores de acceso], [static] y [final]

y también están:

los que pueden ser cambiados por otras opciones [modificadores de acceso] y [valorRetorno]

Y que al realizar estos cambios todo sea "legal" y no estropeen la sobrescritura como cuando se cambian los parámetros?

Correcto ( salvo por el orden de los modificadores de acceso ) Cuando le cambias los parámetros se le llama "sobre carga" ( overload en inglés )

Imagen de ezamudio

Métodos

Pues no los puedes volver estáticos, pero sí puedes definir métodos que se llamen igual pero sean estáticos, aunque no tiene ningún efecto sobre la herencia.

En cuanto a los parámetros, si cambias el tipo lo que estás haciendo es definir un método distinto (sobrecargar el método). Recuerda que puedes tener varios métodos con el mismo nombre pero que reciben distintos tipos o número de parámetros.

Lo que no entiendo es por qué no quieres que se herede. Si lo que necesitas es que tu subclase no haga nada en el método heredable(), simplemente lo puedes redefinir como public void heredable() {} y ya, tu Clase3 no hace nada en ese método.

La palabra final sirve para que ya no se pueda sobreescribir el método; si en Clase2 le pones final entonces en Clase3 ya no puedes sobreescribir el método pero lo sigues heredando (lo puedes invocar todavía desde Clase3). Si en Clase3 lo redefines como dije en el párrafo anterior y además le agregas final, haces que el método ya no haga absolutamente nada y que además las subclases de Clase3 tampoco lo puedan redefinir (pero por qué demonios querrías hacer eso?).

Creo que sería muy útil saber por qué realmente quieres eliminar la herencia; habemos algunos aquí que llevamos años haciendo OOP y creo que nadie ha tenido un problema como el que describes. O tal vez lo quieres hacer solamente por curiosidad?

Imagen de samz550a

Hola ezamudio, realmente si

Hola ezamudio, realmente si es curiosidad, quería despejar unas dudas y confirmar lo que suponía.

Muchas gracias por la ayuda. Saludos.

Imagen de samz550a

Gracias OscarRyz :D has sido

Gracias OscarRyz :D has sido muy explicito con tu respuesta, ya me queda todo mas claro.

Un saludo.