Eu estava pensando, ao criar novas Activity
aulas e, em seguida, substituindo o onCreate()
método, no eclipse Eu sempre se auto acrescentou: super.onCreate()
. Como isso acontece? Existe uma palavra-chave java na classe abstrata ou pai que força isso?
Não sei se é ilegal não chamar a superclasse, mas lembro em alguns métodos que recebi uma exceção lançada por não fazer isso. Isso também está integrado ao java? Você pode usar alguma palavra-chave para fazer isso? Ou como isso é feito?
java
android
overriding
super
Peterdk
fonte
fonte
Respostas:
Aqui está a fonte de
Activity#onCreate()
- são quase todos os comentários ( original - consulte a linha ~ 800 ):/** * Called when the activity is starting. This is where most initialization * should go: calling {@link #setContentView(int)} to inflate the * activity's UI, using {@link #findViewById} to programmatically interact * with widgets in the UI, calling * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve * cursors for data being displayed, etc. * * <p>You can call {@link #finish} from within this function, in * which case onDestroy() will be immediately called without any of the rest * of the activity lifecycle ({@link #onStart}, {@link #onResume}, * {@link #onPause}, etc) executing. * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> * * @param savedInstanceState If the activity is being re-initialized after * previously being shut down then this Bundle contains the data it most * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> * * @see #onStart * @see #onSaveInstanceState * @see #onRestoreInstanceState * @see #onPostCreate */ protected void onCreate(Bundle savedInstanceState) { mVisibleFromClient = !mWindow.getWindowStyle().getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false); mCalled = true; }
então, meu palpite seria que o plug-in ADT Eclipse é o que adiciona automaticamente essa chamada
super.onCreate()
para você. É uma suposição total, no entanto.fonte
mCalled = true
também é usado para uma possível exceção. Talvez não no,onCreate()
mas quando de fato essa exceção for lançada, ele usará esse padrão simples.Isso é adicionado à biblioteca de anotações de suporte:
dependencies { compile 'com.android.support:support-annotations:22.2.0' }
http://tools.android.com/tech-docs/support-annotations
@CallSuper
fonte
Se você quiser forçar as subclasses a executar a lógica da classe pai, um padrão comum é algo como o seguinte:
public abstract class SuperClass implements SomeInterface { // This is the implementation of the interface method // Note it's final so it can't be overridden public final Object onCreate() { // Hence any logic right here always gets run // INSERT LOGIC return doOnCreate(); // If you wanted you could instead create a reference to the // object returned from the subclass, and then do some // post-processing logic here } protected abstract Object doOnCreate(); } public class Concrete extends SuperClass { @Override protected Object doOnCreate() { // Here's where the concrete class gets to actually do // its onCreate() logic, but it can't stop the parent // class' bit from running first return "Hi"; } }
Na verdade, isso não responde à sua pergunta sobre o que faz o Eclipse inserir automaticamente uma chamada de superclasse na implementação; mas não acho que seja o caminho a seguir, pois isso sempre pode ser excluído.
Você não pode realmente impor que um método deve chamar a versão da superclasse com uma palavra-chave Java ou algo parecido. Suspeito que suas exceções simplesmente vieram de algum código na classe pai verificando invariantes esperados, ou algo, que foram invalidados por sua abordagem. Observe que isso é sutilmente diferente de lançar uma exceção porque você falhou ao chamar
super.onCreate()
.fonte
Se você quiser ter certeza absoluta de que o método da superclasse também é chamado, você deve se enganar um pouco: não permita que o método da superclasse seja sobrescrito, mas faça com que ele chame um método protegido que pode ser substituído.
class Super { public final void foo() { foo_stuff(); impl_stuff(); } protected void impl_stuff() { some_stuff_that_you_can_override(); } } class Base extends Super { protected void impl_stuff() { my_own_idea_of_impl(); } }
Dessa forma, o usuário deve chamar Super.foo () ou Base.foo () e sempre será a versão da classe base como foi declarada como final. O material específico da implementação está em impl_stuff (), que pode ser sobrescrito.
fonte
Para responder à sua pergunta real, a autocriação da chamada para super.onCreate () é um recurso do plugin ADT. Em java, você não pode forçar diretamente uma subclasse a chamar a superimplementação de um método, afaik (consulte o padrão descrito em outras respostas para uma solução alternativa). No entanto, lembre-se de que, no Android, você não está instanciando objetos Activity (ou objetos Service) diretamente - você passa um Intent para o sistema e o sistema instancia o objeto e chama onCreate () sobre ele (junto com outros métodos de ciclo de vida). Portanto, o sistema tem uma referência de objeto direta para a instância Activity e é capaz de verificar (presumivelmente) algum Booleano definido como verdadeiro na implementação da superclasse de onCreate (). Embora eu não saiba exatamente como é implementado, provavelmente se parece com isto:
class Activity { onCreate() { superCalled = true; ... } ... }
E na classe de nível "sistema" que recebe o Intent e instancia o objeto Activity a partir dele:
... SomeActivitySubclass someActivitySubclassObject = new SomeActivitySubclass(); someActivitySubclassObject.onCreate(); if (!someActivityObject.isSuperCalled()) { Exception e = new Exception(...) //create an exception with appropriate details throw e; }
Meu palpite é que provavelmente é um pouco mais complexo do que isso, mas essa é a ideia. O Eclipse cria automaticamente a chamada porque o plug-in ADT o instrui, por conveniência. Boa codificação!
fonte
Não há nada em Java que force a chamada de super e há muitos exemplos em que você não gostaria. O único lugar onde você pode forçar a chamada de super é nos construtores. Todos os construtores precisam chamar um construtor de superclasse. Um (o construtor sem argumentos) será inserido se você não escrever um explicitamente, e se não houver nenhum construtor sem argumentos, você deverá chamá-lo explicitamente.
fonte
O Eclipse está apenas sendo útil, lembrando que você pode chamar a implementação da superclasse se desejar.
provavelmente você está obtendo um erro porque não está fazendo algo necessário que a superclasse faz, já que não está chamando sua implementação.
fonte
O Eclipse apenas ajuda você a fazer as coisas certas e evitar exceções.
De http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle )
fonte