Quando eu faço minha própria classe personalizada Android, eu uso extend
sua classe nativa. Então, quando eu quiser substituir o método base, eu sempre chamo super()
método, assim como eu sempre faço em onCreate
, onStop
, etc.
E eu pensei que era isso, desde o início a equipe do Android nos aconselhou a sempre chamar super
todos os métodos de substituição.
Mas, em muitos livros , posso ver que os desenvolvedores, mais experientes do que eu, muitas vezes omitem a chamada super
e eu realmente duvido que eles façam isso por falta de conhecimento. Por exemplo, olhe para isto básica SAX classe do analisador, onde super
é omitido na startElement
, characters
e 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
}
}
}
Se você tentar criar qualquer método de substituição via Eclipse ou qualquer outro IDE, super
sempre será criado como parte do processo automatizado.
Este foi apenas um exemplo simples. Os livros estão cheios de códigos semelhantes .
Como eles sabem quando você deve ligar super
e quando pode omitir a ligação?
PS. Não se vincule a este exemplo específico. Foi apenas um exemplo escolhido aleatoriamente entre muitos exemplos.
(Pode parecer uma pergunta de iniciante, mas estou muito confuso.)
fonte
endElement
O documento da API de diz "Por padrão, não faça nada. Os criadores de aplicativos podem sobrescrever este método ...", o que significa que você pode chamar super com segurança porque ele não faz "nada", mas você não precisa e pode realmente sobrescrevê-lo. Freqüentemente, você pode dizer se precisa / pode / não deve fazer isso se ler o documento desse método.Respostas:
Ao chamar o
super
método, você não está substituindo o comportamento do método, está estendendo -o.Uma chamada para
super
executará qualquer lógica que a classe que você está estendendo tenha definido para esse método. Leve em consideração que pode ser importante o momento em que você chamasuper
a implementação na substituição de seu método. Por exemplo:Uma chamada para
B.save()
executará asave()
lógica paraA
eB
, nesta ordem particular. Se você não ligasse parasuper.save()
dentroB.save()
,A.save()
não seria chamado. E se você ligassesuper.save()
depoissave(b)
,A.save()
seria efetivamente executado depoisB.save()
.Se você deseja sobrescrever
super
o comportamento de (ou seja, ignorar totalmente sua implementação e fornecer tudo sozinho), você não deve chamarsuper
.No
SAXParser
exemplo que você fornece, as implementações deDefaultHandler
para esses métodos estão simplesmente vazias, de modo que as subclasses podem substituí-las e fornecer um comportamento para esses métodos. No javadoc para esse método, isso também é indicado.Sobre a
super()
chamada padrão no código gerado por IDEs, conforme@barsju
apontado em seu comentário, em cada construtor há uma chamada implícita parasuper()
(mesmo que você não escreva em seu código), o que significa, nesse contexto, uma chamada parasuper
' s construtor padrão. EleIDE
apenas anota para você, mas também seria chamado se você o removesse. Observe também que, ao implementar construtores,super()
ou qualquer uma de suas variantes com argumentos (ou seja,super(x,y,z)
) só podem ser chamados no início do método.fonte
super()
(o construtor padrão da superclasse) é sempre chamado, mesmo que você não o especifique. Se a superclasse não tiver um construtor padrão, você obterá um erro de compilação se não chamar explicitamente um dos construtores da superclasse como sua primeira instrução no construtor da subclasse.Normalmente, se um método de API especial tem um significado crítico para o ciclo de vida do contexto da estrutura subjacente, ele sempre será declarado explicitamente e destacado na documentação da API, como a
Activity.onCreate()
documentação da API . Além disso, se a API segue um design robusto, deve lançar algumas exceções para alertar o desenvolvedor consumidor no tempo de compilação do projeto e garantir que não gere uma falha no tempo de execução.Se isso não for declarado explicitamente na documentação da API, é bastante seguro para o desenvolvedor do consumidor assumir que o método da API não é obrigatório para chamar ao substituí-lo. Cabe ao desenvolvedor consumidor decidir se deve usar o comportamento padrão (chamar o
super
método) ou substituí-lo completamente.Se a condição for permitida (adoro software de código aberto), o desenvolvedor consumidor pode sempre verificar o código-fonte da API e ver como o método está realmente escrito nos bastidores. Verifique a
Activity.onCreate()
fonte e aDefaultHandler.startElement()
fonte, por exemplo.fonte
O teste que você deve fazer em sua cabeça é:
"Eu quero que todas as funcionalidades deste método sejam feitas para mim e, em seguida, faço algo depois?" Se sim, então você deseja chamar
super()
e, em seguida, finalizar seu método. Isso será verdadeiro para métodos "importantes" comoonDraw()
, que manipula muitas coisas em segundo plano.Se você deseja apenas algumas das funcionalidades (como a maioria dos métodos que você substituirá), provavelmente não deseja chamar
super()
.fonte
Bem, Xavi deu uma resposta melhor .. mas você provavelmente deve saber o que
super()
faz quando chamado em um método sobrescrito ... ele mostra o que você fez com o comportamento padrão ..por exemplo:
método na classe de visualização quando substituído .. você desenha algo antes de dizer super.onDraw (), ele aparece quando a visualização é totalmente desenhada .. então aqui
super
é necessário chamar uma vez que o Android tem algumas coisas criticamente importantes a fazer (como onCreate ())mas ao mesmo tempo
quando você sobrescreve isto, você não quer chamar super porque abre uma caixa de diálogo com uma lista de opções para um EditText ou qualquer outra visão semelhante .. Essa é a diferença básica .. você tem a opção de deixá-la algumas vezes .. mas por outros métodos como
onCreate() , onStop()
você deve deixar o sistema operacional lidar com isso.fonte
Não entendi claramente sua pergunta, mas se você está perguntando por que não chamar o
super
método:Há uma razão para chamar o
super
método: se não houver nenhum construtor de argumento zero na classe pai, então não é possível fazer uma classe filha para isso, então você precisa manter um construtor sem argumento na classe pai ou você precisa para definir asuper()
instrução de chamada comargument(how much argument constructor you have used in super class)
no topo do construtor da classe filha.Eu espero que isso ajude. Se não, me avise.
fonte
Eu implementei uma lista de matriz de restrição como
Se você olhar o código, ele simplesmente fará uma pré-verificação antes de realmente permitir que a superclasse execute a adição real do elemento à lista. Isso mostra um dos dois motivos para a substituição do método:
fonte
Para aqueles que também se perguntaram quais métodos substituídos do Android Framework deveriam ser chamados
super
e encontraram esta pergunta - aqui está uma dica atual de 2019 - o Android Studio 3+ dirá quando você precisar .fonte