java - referencia - super();
Requerir anulación de método para llamar super (6)
Quiero que cuando una clase secundaria invalida un método en una clase primaria, se super.method()
en ese método secundario.
¿Hay alguna manera de comprobar esto en tiempo de compilación?
Si no es así, ¿cómo hago para lanzar una excepción de tiempo de ejecución cuando esto sucede?
solución:
Mira el proyecto findBugs ...
- FindBugs
- Paquete de anotaciones
Ejemplo ...
import javax.annotation.OverridingMethodsMustInvokeSuper;
:
@OverridingMethodsMustInvokeSuper
protected String getLabel(){
...
}
Anular:
@Override
protected String getLabel(){
// no call to Super Class!!
// gives a message
...
}
Lo he estado usando durante unos 3 años. Ningún gatito ha sido dañado.
¿Qué tal si haces la llamada tú mismo? En lugar de dictar la implementación a una subclase (lo que realmente no se puede hacer), simplemente aplíquela con la interfaz y la implementación de su clase base.
public abstract class BaseClass {
public final void callMeFirst() {
// method that needs to be called before subclassing method runs
}
public final void makeSureWhateverGetsCalled() {
callMeFirst();
overrideMe();
}
public abstract void overrideMe();
}
public class OverridingClass extends BaseClass {
@Override
public void overrideMe() {
// do whatever needs to be done AFTER callMeFirst() is run
}
}
Bueno, puedo suponer que la inicialización en el método de superclase se usa en otros lugares. Definiría una marca en el método de superclase y la comprobaría más tarde cuando se necesite la inicialización. Más específicamente, digamos que setupPaint () es un método de superclase que siempre debe llamarse. entonces podemos hacer
class C {
private boolean paintSetupDone = false;
void setupPaint() {
paintSetupDone = true;
...
}
void paint() { // requires that setupPaint() of C has been called
if (!paintSetupDone) throw RuntimeException("setup not done");
...
}
}
Ahora, si una subclase de C no llama a la función setupPaint (), no hay forma de que se establezca el indicador (privado), y los métodos que requieren la llamada contractual a la superclase setupPaint (), como paint (), podrán Para comprobar y lanzar esa excepción.
Como se señaló en otra parte, por cierto, no hay forma de exigir un contrato de este tipo en Java.
No hay manera de requerir esto directamente. Lo que puedes hacer, sin embargo, es algo como:
public class MySuperclass {
public final void myExposedInterface() {
//do the things you always want to have happen here
overridableInterface();
}
protected void overridableInterface() {
//superclass implemention does nothing
}
}
public class MySubclass extends MySuperclass {
@Override
protected void overridableInterface() {
System.out.println("Subclass-specific code goes here");
}
}
Esto proporciona un punto de interfaz interno que las subclases pueden usar para agregar un comportamiento personalizado al método público myExposedInterface()
, mientras se asegura que el comportamiento de la superclase siempre se ejecuta sin importar lo que haga la subclase.
No hay una manera de verificar esto en tiempo de compilación. (Sin embargo, he escuchado sugerencias de que podría hacer esto en tiempo de compilación con anotaciones, aunque nunca he visto una solución de anotación específica y no sé cómo se haría). Para una manera de lanzar una excepción en tiempo de ejecución, ver este hilo . Quizás pueda refactorizar su código para que la clase base tenga un método final
que incluya las partes esenciales y llame a un método no final que no requiera una super
llamada.
desafortunadamente, no hay manera de exigirlo en el momento de la compilación, y no hay manera de detectarlo en tiempo de ejecución (a menos que exista alguna lógica específica de la aplicación o secuencia de eventos que pueda usar para detectar el método que no se llama). Lo mejor que se puede hacer es documentar el método en gran medida.
Si realmente quieres seguir este camino, podrías usar algo como este patrón:
public class BaseClass {
public final void myMethod() {
// do special stuff here which must always happen ...
// allow subclasses to customize myMethod() here
myMethodCustom();
}
protected void myMethodCustom() {
// base class does nothing
}
}