Android – cómo forzar a que el niño reemplace el método padre que tiene código

Aquí está el escenario -> imagine que hay 3 clases, quiero hacer algo como:

public class GameObject { public void updateBounds() { // do something } } public abstract class Enemy extends GameObject { public abstract void updatePosition(){ //<-- this will not compile, //but this is what i want to do, to force //child to override parent method updateBounds(); } } public class Minion extends Enemy { @Override public void updatePosition() { super.updatePosition(); // <-- how do i throw an exception if this line // is not called within this method of the // child? // now do something extra that only Minion knows how to do } } 
  • ¿Cómo diseñar la clase Enemigo para que tenga un método que haga algo, pero requiere que todos los niños lo reemplacen?
  • ¿Cómo forzar al niño (que tuvo que anular el método) para llamar también al método de los padres?

Esto es casi como la clase de Activity de Android que tiene el onCreate, onStart, onResume … etc. Métodos que son opcionales, pero si usted hace uso de él, le obliga a llamar a super. No puede ser abstracto porque quiero que se ejecute algún código cuando se llama al método (que sólo está en el método de la clase primaria). Puntos de bonificación si sabes cómo lo hicieron de esta manera?

Las fuentes de Android utilizan un booleano llamado mCalled que se establece en true dentro de la implementación del método cuasi-abstracto. En su caso que estaría dentro de la updatePosition() original updatePosition() .

Entonces, cuando quiera llamar a updatePosition() , updatePosition() a través de esto:

 private void performUpdatePosition() { mCalled = false; updatePosition(); if (!mCalled) throw new SuperNotCalledException(); } 

Y updatePosition() se vería así

 protected void updatePosition() { mCalled = true; updateBounds(); } 

EDITAR:

Ahora que lo pienso, la forma en que android lo hace es un poco redonda alrededor. Debido a que todas las llamadas a updatePosition() están pasando por performUpdatePosition() , ya no es necesario tener algún código dentro de updatePosition() que se puede sobreescribir, pero no debería.

Un enfoque mucho mejor es simplemente mover las acciones requeridas a performUpdatePosition() :

 private void performUpdatePosition() { updateBounds(); updatePosition(); } protected void updatePosition() { //Do nothing by default } 

De esta manera, el receptor no tiene que preocuparse por llamar a super.updatePosition . Si la subclase no anula esa función, entonces nada extra ocurrirá, mientras que si lo hacen, la anulación agregará al comportamiento anterior.

Quizás en vez de usted que llama el método del niño, usted podría definir un método bajo en la clase

 public void updatePosition() { //do what you need to do before the child does it's stuff onUpdatePosition(); //do what you need to do after the child does it's stuff } protected abstract void onUpdatePosition(); 

De esa manera, como usted llama a updatePosition (), el niño tiene que tener su propia onUpdatePosition () y usted sabe que lo que el padre hace sucede cada vez

¿Cómo diseñar la clase Enemigo para que tenga un método que haga algo, pero requiere que todos los niños lo reemplacen?

Para ello, los métodos de su clase padre deben definirse como método abstracto, es decir, sólo la forma en que la clase hijo sabe que el método definido en la clase padre debe definirse en la clase secundaria.

¿Cómo forzar al niño (que tuvo que anular el método) para llamar también al método de los padres?

La sustitución de un método se realiza si la clase padre es clase abstracta.

qué tal si

 public abstract class Enemy extends GameObject{ public abstract void updatePositionCommon(){ //code common to all updatePosition(); } public abstract void updatePosition(){ //override this method in children } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.