java - programacion - ¿Por qué tenemos que llamar super en Android a veces?
manual de android en pdf (6)
A veces, cuando anulo los métodos, recibo una excepción la primera vez que se llama como a continuación:
05-31 21:32:04.266: E/AndroidRuntime(28471): android.support.v4.app.SuperNotCalledException:
Fragment AnalFragment{41795860 #1 id=0x7f070002} did not call through to super.onDestroy()
¿Por qué estamos obligados a llamar a super.method()
? Tiene sentido que existan obligaciones por parte de la clase de padres, pero lo más importante, ¿cómo sabemos que un método requiere que se llame super
, en lugar de esperar que se bloquee?
¿Por qué estamos obligados a llamar a super.method ()?
Las clases que componen el SDK de Android pueden ser increíblemente complejas. Por ejemplo, tanto las actividades como los fragmentos deben realizar una serie de operaciones para funcionar correctamente (es decir, administrar el ciclo de vida, optimizar el uso de la memoria, dibujar el diseño en la pantalla, etc.). Requerir que el cliente realice una llamada a la clase base (a menudo al comienzo del método) garantiza que estas operaciones se sigan realizando, a la vez que proporciona un nivel de abstracción razonable para el desarrollador.
¿Cómo sabemos que un método de
funciónrequiere que se llame súper?
La documentación debe indicarle si esto es obligatorio o no. Si no lo hiciera, buscaría Google en algún código de muestra (o verificaría las demostraciones de la API ... o mejor aún, ¡mira el código fuente!). No debería ser demasiado difícil de entender.
Como básico, super es un método usado para referirse al campo / método de superclase principal desde el que se realiza la extensión de clase (el uso se extiende en la definición de clase inicial) o desde qué instancia se crea.
Cuando necesitamos una definición más básica para alterar el método / campo de la superclase que se utilizará para resolver nuestro propósito.
por ejemplo
java.lang.Object (tiene muchos métodos y campos)> android.view.View> android.view.ViewGroup> android.widget.LinearLayout
Pero si necesita cambiar / usar ya que es un método de la clase de objeto, entonces necesita el método Súper para referir el primer método creado en la clase de objeto dentro de la clase LinearLayout.
El requisito generalmente se especifica directamente en la documentación de la API. Por ejemplo, vea android.widget.ListView.onFinishInflate:
vacío protegido en FinalInflación ()
...
Incluso si la subclase prevalece sobre FinalInflate, siempre deben asegurarse de llamar al método super, para que nos llamen.
Lamentablemente, mi experiencia personal es que los documentos de Android tienen una calidad desigual. Entonces, sospecho que hay casos donde se requiere la llamada pero no está documentada como tal.
Es importante tener en cuenta que una vez que anula un método, básicamente ignora todo lo que estaba en la clase principal y en su lugar tiene su propia implementación personalizada en la clase secundaria (literalmente sobrescribiéndola).
En nuestro caso, no deseamos descartar la implementación principal. De hecho, queremos seguir utilizando el método original y AGREGAR los controles adicionales para cada clase de niño de forma individual.
¡Aquí es donde usamos la palabra clave "súper"!
Se le permite reutilizar el método principal en la clase secundaria utilizando la palabra clave "super", seguido de un punto y luego el nombre del método:
por ejemplo: isValidMove (posición) es un método para las piezas de ajedrez y verifica la validez del movimiento y el límite en el tablero de ajedrez de 8x8.
super.isValidMove (posición);
El uso de la palabra clave super aquí significa que queremos ejecutar el método real en la clase super (o principal) desde dentro de la implementación en "esta" clase.
Lo que significa que en cada una de las clases secundarias, antes de que compruebe el movimiento personalizado, puede verificar si super.isValidMove (posición) ha devuelto falso. Si es así, entonces no es necesario hacer más controles e inmediatamente devolver falso; de lo contrario, continúe revisando.
La nueva implementación para la clase Rook se verá así:
class Rook extends Piece{
boolean isValidMove(Position newPosition){
// First call the parent''s method to check for the board bounds
if(!super.isValidMove(position)){
return false;
}
// If we passed the first test then check for the specific rock movement
if(newPosition.column == this.column && newPosition.row == this.row){
return true;
}
else{
return false;
}
}
}
También puede usar super () para llamar al constructor principal. Esto generalmente se hace cuando se implementa el constructor del niño. Por lo general, le conviene primero ejecutar todo en el constructor principal y luego agregar más código en el constructor del elemento secundario:
class Rook extends Piece{
// default constructor
public Rook(){
super(); // this will call the parent''s constructor
this.name = "rook";
}
}
Nota: Si el constructor de un niño no llama explícitamente al constructor del padre usando super, el compilador de Java automáticamente inserta una llamada al constructor predeterminado de la clase padre. Si la clase padre no tiene un constructor predeterminado, obtendrá un error en tiempo de compilación.
La palabra clave super tiene dos usos principales
1. Llama al constructor de la superclase.
2. Acceda a un miembro de la superclase que ha sido ocultado por un miembro de una subclase.
Entonces, ¿por qué necesitamos usar palabras clave super a veces? La respuesta sería que Android viene bajo el lenguaje 4GL, lo que significa que tiene muchas funcionalidades listas. Si bien estamos reemplazando estos métodos para la personalización, utilizamos la palabra clave super.
ver el uso muy simple de la palabra clave super en Android (como lo hacemos la mayor parte del tiempo).
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
.
.
.
}
super () debe ser siempre la primera instrucción ejecutada dentro del constructor de una subclase. Cuando una subclase llama a super (), llama al constructor de su superclase inmediata. La segunda forma de super es más aplicable a situaciones en las que los nombres de miembros de una subclase ocultan miembros con el mismo nombre en la superclase.
Sé que esta no es la verdadera intención del OP, hizo esta pregunta y no creo que haya recibido una respuesta muy buena, así que si alguien se pregunta alguna vez "¿Por qué diablos TENGO que llamarme super?!? Si lo van a necesitar, ¿por qué no lo hacen por mí solo? ". Aquí está la respuesta a esas preguntas ...
Básicamente, super () es algo que se debe invocar si se está sobrescribiendo algo que DEBE llamarse, que a menudo puede ser un código bastante complicado. ¡Ahora, la razón por la que no solo lo hacen por usted y lo llaman antes de su función es principalmente para que tenga el control! :-RE
Para ser más específico, no puedes controlar SI llamas a super (), ¡sin embargo, puedes controlar CUÁNDO! Entonces, digamos que tiene un código específico que debe suceder ANTES de que se llame a super (), ahora tiene la libertad de llamar a super () solo después de ejecutar su código. O ... digamos que requiere que super () ya se haya ejecutado para que su código no se cuelgue, ahora tiene la opción de ejecutar super () antes de ejecutar su código, por lo tanto, asegúrese de que todo esté configurado para usted. Diablos, incluso podrías anular técnicamente el hardcore de la clase superior y codificar tu propio método que se encarga de super (), y hacerlo para que no tengas que llamar a super (), pero el 99.9% de las personas sensatas no necesitarán ¡para hacer esto! :-PAG
Por lo tanto, la respuesta breve a "¿por qué tengo que llamar a super ()" es ... para que pueda controlar cuándo se llama y hacer las cosas antes, o después de que se ejecute super ()? :-)