Zastanawiałem się, podczas tworzenia nowych Activity
klas, a następnie przesłanianie onCreate()
metody w Eclipse zawsze dotrzesz automatycznego dodania: super.onCreate()
. Jak to się stało? Czy istnieje słowo kluczowe java w klasie abstrakcji lub nadrzędnej, które to wymusza?
Nie wiem, czy niewywołanie superklasy jest nielegalne, ale pamiętam, że w niektórych metodach został zgłoszony wyjątek, ponieważ tego nie robię. Czy jest to również wbudowane w Javę? Czy możesz użyć do tego słowa kluczowego? Albo jak to się robi?
java
android
overriding
super
Peterdk
źródło
źródło
Odpowiedzi:
Oto źródło
Activity#onCreate()
- to prawie wszystkie komentarze ( oryginał - patrz wiersz ~ 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; }
więc przypuszczam, że wtyczka ADT Eclipse jest tym, do czego automatycznie dodaje to wywołanie
super.onCreate()
. Ale to całkowite przypuszczenie.źródło
mCalled = true
również jest używany do ewentualnego wyjątku. Może nie w,onCreate()
ale jeśli rzeczywiście taki wyjątek zostanie zgłoszony, użyje tego prostego wzorca.To jest dodawane w bibliotece adnotacji wsparcia:
dependencies { compile 'com.android.support:support-annotations:22.2.0' }
http://tools.android.com/tech-docs/support-annotations
@CallSuper
źródło
Jeśli chcesz zmusić podklasy do wykonywania logiki klasy nadrzędnej, typowy wzorzec jest podobny do następującego:
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"; } }
To właściwie nie odpowiada na twoje pytanie, co skłania Eclipse do automatycznego wstawiania wywołania nadklasy do implementacji; ale nie sądzę, aby tak było, ponieważ zawsze można to usunąć.
W rzeczywistości nie można wymusić, że metoda musi wywoływać wersję nadklasy za pomocą słowa kluczowego Java lub czegoś podobnego. Podejrzewam, że twoje wyjątki pochodzą po prostu z jakiegoś kodu w klasie nadrzędnej sprawdzającego oczekiwane niezmienniki lub coś, co zostało unieważnione przez twoje podejście. Zwróć uwagę, że różni się to nieco od zgłaszania wyjątku, ponieważ nie udało się wywołać
super.onCreate()
.źródło
Jeśli chcesz mieć absolutną pewność, że wywoływana jest również metoda nadklasy, musisz trochę oszukać: Nie zezwalaj na nadpisywanie metody nadklasy, ale pozwól jej wywołać metodę chronioną nadpisywalną.
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(); } }
W ten sposób użytkownik musi wywołać Super.foo () lub Base.foo () i zawsze będzie to wersja klasy bazowej, tak jak została zadeklarowana jako ostateczna. Rzeczy specyficzne dla implementacji znajdują się w impl_stuff (), które można nadpisać.
źródło
Aby odpowiedzieć na twoje aktualne pytanie, automatyczne tworzenie wywołania super.onCreate () jest funkcją wtyczki ADT. W Javie nie można bezpośrednio zmusić podklasy do wywołania super implementacji metody, afaik (obejrzyj wzorzec opisany w innych odpowiedziach w celu obejścia problemu). Należy jednak pamiętać, że w systemie Android nie tworzysz instancji obiektów Activity (lub obiektów Service) bezpośrednio - przekazujesz Intent do systemu, a system tworzy instancję obiektu i wywołuje onCreate () na nim (wraz z innymi metodami cyklu życia). Tak więc system ma bezpośrednie odwołanie do obiektu do instancji Activity i jest w stanie sprawdzić (prawdopodobnie) niektóre wartości logiczne, które są ustawione na true w implementacji onCreate () nadklasy. Chociaż nie wiem dokładnie, jak jest zaimplementowany, prawdopodobnie wygląda to mniej więcej tak:
class Activity { onCreate() { superCalled = true; ... } ... }
A w klasie poziomu „systemowego”, która odbiera intencję i tworzy z niej instancję obiektu Activity:
... SomeActivitySubclass someActivitySubclassObject = new SomeActivitySubclass(); someActivitySubclassObject.onCreate(); if (!someActivityObject.isSuperCalled()) { Exception e = new Exception(...) //create an exception with appropriate details throw e; }
Domyślam się, że jest to prawdopodobnie nieco bardziej złożone, ale masz pomysł. Eclipse automatycznie tworzy połączenie, ponieważ wtyczka ADT nakazuje mu to dla wygody. Miłego kodowania!
źródło
W Javie nie ma nic, co wymusza wywoływanie super, i jest wiele przykładów, kiedy nie chcesz. Jedyne miejsce, w którym możesz wymusić wywołanie super, to konstruktorzy. Wszyscy konstruktorzy muszą wywołać konstruktora nadklasy. Jeden (konstruktor bez argumentów) zostanie wstawiony, jeśli nie napiszesz go jawnie, a jeśli nie ma konstruktora bez argumentów, musisz go wywołać jawnie.
źródło
Eclipse jest po prostu pomocny, przypominając ci, że możesz wywołać implementację nadklasy, jeśli chcesz.
prawdopodobnie otrzymujesz błąd, ponieważ nie robisz czegoś koniecznego, co robi superklasa, ponieważ nie wywołujesz jej implementacji.
źródło
Eclipse po prostu pomaga robić wszystko dobrze i unikać wyjątków.
Z http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle )
źródło