Cuando creo mi propia clase personalizada de Android, extend
su clase nativa. Entonces cuando quiero anular el método de base, siempre llamo super()
método, al igual que siempre hago en onCreate
, onStop
, etc.
Y pensé que esto era todo, ya que desde el principio el equipo de Android nos aconsejó que siempre invocáramos super
cada anulación de método.
Pero, en muchos libros puedo ver que los desarrolladores, con más experiencia que yo, a menudo omiten las llamadas super
y realmente dudo que lo hagan por falta de conocimiento. Por ejemplo, observe esta clase de analizador SAX básica donde super
se omite en startElement
, characters
y endElement
:
public class SAXParser extends DefaultHandler{
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
//do something
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}else () {
//do something
}
}
}
Si intenta crear cualquier método de anulación a través de Eclipse o cualquier otro IDE, super
siempre se creará como parte del proceso automatizado.
Este fue solo un ejemplo simple. Los libros están llenos de códigos similares .
¿Cómo saben cuándo debe llamar super
y cuándo puede omitirlo?
PD. No se limite a este ejemplo específico. Fue solo un ejemplo elegido al azar de muchos ejemplos.
(Esto puede parecer una pregunta para principiantes, pero estoy realmente confundido).
fuente
endElement
El documento de la API dice "De forma predeterminada, no hacer nada. Los escritores de aplicaciones pueden anular este método ...", lo que significa que puede llamar de forma segura a super porque no hace "nada", pero no es necesario y realmente puede anularlo. A menudo puede saber si tiene que / puede / no debe hacerlo si lee el documento de ese método.Respuestas:
Al llamar al
super
método, no está anulando el comportamiento del método, lo está extendiendo .Una llamada a
super
ejecutará cualquier lógica que la clase que está extendiendo haya definido para ese método. Tenga en cuenta que podría ser importante en el momento en que llame asuper
la implementación de su método overriding. Por ejemplo:Una llamada a
B.save()
realizará lasave()
lógica para ambosA
yB
, en este orden en particular. Si no estuvieras llamandosuper.save()
adentroB.save()
,A.save()
no te llamarían. Y si llamasuper.save()
despuéssave(b)
,A.save()
se realizará efectivamente despuésB.save()
.Si desea anular
super
el comportamiento (es decir, ignorar completamente su implementación y proporcionarlo todo usted mismo), no debería llamarsuper
.En el
SAXParser
ejemplo que proporciona, las implementaciones deDefaultHandler
para esos métodos están simplemente vacías, por lo que las subclases pueden anularlas y proporcionar un comportamiento para esos métodos. En el javadoc para este método esto también se señala.Acerca de la
super()
llamada predeterminada en el código generado por los IDE, como se@barsju
señala en su comentario, en cada constructor hay una llamada implícita asuper()
(incluso si no la escribe en su código), lo que significa, en ese contexto, una llamada asuper
' s constructor predeterminado. ElIDE
simplemente lo escribe para usted, sino que también se llama si se la ha quitado. También observe que cuando se implementan constructores,super()
o cualquiera de sus variantes con argumentos (es decirsuper(x,y,z)
), solo se puede llamar al principio del método.fuente
super()
(el constructor predeterminado de la superclase) siempre se llama, incluso si no lo especifica. Si la superclase no tiene un constructor predeterminado, obtendrá un error de compilación si no llama explícitamente a uno de los constructores de la superclase como su primera declaración en el constructor de subclase.Por lo general, si un método API especial tiene un significado crítico para el ciclo de vida del contexto del marco subyacente, siempre se indicará y destacará explícitamente en la documentación de la API, como la
Activity.onCreate()
documentación de la API . Además, si la API sigue un diseño robusto, debería generar algunas excepciones para alertar al desarrollador consumidor en el tiempo de compilación del proyecto y asegurarse de que no generará una falla en el tiempo de ejecución.Si esto no se indica explícitamente en la documentación de la API, entonces es bastante seguro para el desarrollador consumidor asumir que no es obligatorio llamar al método API al anularlo. Depende del desarrollador consumidor decidir si utilizar el comportamiento predeterminado (llamar al
super
método) o anularlo por completo.Si la condición está permitida (me encanta el software de código abierto), el desarrollador consumidor siempre puede consultar el código fuente de la API y ver cómo está escrito realmente el método bajo el capó. Ver
Activity.onCreate()
fuente y laDefaultHandler.startElement()
fuente, por ejemplo.fuente
La prueba que debes hacer en tu cabeza es:
"¿Quiero hacerme todas las funciones de este método y luego hacer algo?" Si es así, entonces desea llamar
super()
y luego terminar su método. Esto será cierto para métodos "importantes" comoonDraw()
, que maneja muchas cosas en segundo plano.Si solo desea parte de la funcionalidad (como con la mayoría de los métodos que anulará), probablemente no desee llamar
super()
.fuente
Bueno, Xavi dio una mejor respuesta ... pero probablemente sepas lo que hace
super()
cuando se le llama en un método anulado ... anuncia lo que ha hecho con el comportamiento predeterminado ...p.ej:
método en la clase de vista cuando se anula ... dibuja algo antes de decir super.onDraw () aparece una vez que la vista está completamente dibujada ... así que aquí
super
es necesario llamar ya que Android tiene algunas cosas críticamente importantes que hacer (como onCreate ())pero al mismo tiempo
cuando anula esto, no quiere llamar a super porque abre un cuadro de diálogo con una lista de opciones para un EditText o cualquier otra vista similar .. Esa es la diferencia básica .. tiene la opción de dejarla algunas veces .. pero por otros métodos como
onCreate() , onStop()
usted debería dejar que el sistema operativo lo maneje ..fuente
No recibí su pregunta claramente, pero si está preguntando por qué no llamar al
super
método:Hay una razón para llamar al
super
método: si no hay un constructor de argumento cero en la clase principal, entonces no es posible crear una clase secundaria para eso, por lo que debe mantener un constructor sin argumentos en la clase principal o necesita para definir lasuper()
instrucción de llamadaargument(how much argument constructor you have used in super class)
en la parte superior del constructor de la clase secundaria.Espero que esto ayude. Si no, avíseme.
fuente
Implementé una lista de matriz de restricciones como
Si observa el código, simplemente realiza una verificación previa antes de permitir que la superclase realice la adición real del elemento a la lista. Esto indica una de las dos razones por las que se reemplaza el método:
fuente
Para aquellos que también se preguntaron qué métodos anulados de Android Framework deberían llamar
super
y encontraron esta pregunta (aquí hay una pista actual de 2019), Android Studio 3+ le dirá cuándo lo necesita .fuente