Мне было интересно, при создании новых Activity
классов , а затем перекрывая onCreate()
метод, в затмении я всегда получить авто добавил: super.onCreate()
. Как это произошло? Есть ли ключевое слово java в абстрактном или родительском классе, которое вызывает это?
Я не знаю, незаконно ли не вызывать суперкласс, но я помню, что в некоторых методах у меня возникло исключение из-за того, что я этого не сделал. Это тоже встроено в Java? Вы можете использовать какое-нибудь ключевое слово для этого? Или как это делается?
java
android
overriding
super
Петердк
источник
источник
Ответы:
Вот источник
Activity#onCreate()
- это почти все комментарии ( оригинал - см. Строку ~ 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; }
Итак, я предполагаю, что плагин ADT Eclipse - это то, что автоматически добавляет этот вызов
super.onCreate()
для вас. Хотя это полное предположение.источник
mCalled = true
также используется для возможного исключения. Возможно, не в,onCreate()
но когда действительно создается такое исключение, он будет использовать этот простой шаблон.Это добавлено в библиотеку аннотаций поддержки:
dependencies { compile 'com.android.support:support-annotations:22.2.0' }
http://tools.android.com/tech-docs/support-annotations
@CallSuper
источник
Если вы хотите заставить подклассы выполнять логику родительского класса, общий шаблон выглядит примерно так:
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"; } }
Это фактически не отвечает на ваш вопрос о том, что побуждает Eclipse автоматически вставлять вызов суперкласса в реализацию; но я не думаю, что это все равно что делать, так как это всегда можно удалить.
На самом деле вы не можете заставить метод вызывать версию суперкласса с ключевым словом Java или чем-то подобным. Я подозреваю, что ваши исключения просто возникли из-за какого-то кода в родительском классе, проверяющего ожидаемые инварианты или что-то еще, что было признано недействительным из-за вашего подхода. Обратите внимание, что это немного отличается от вызова исключения из-за того, что вы не смогли вызвать
super.onCreate()
.источник
Если вы хотите быть абсолютно уверены, что метод суперкласса также вызывается, вы должны немного обмануть: не позволяйте перезаписывать метод суперкласса, но пусть он вызывает переопределяемый защищенный метод.
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(); } }
Таким образом, пользователь должен вызвать Super.foo () или Base.foo (), и это всегда будет версия базового класса, поскольку она была объявлена как final. Все, что связано с реализацией, находится в impl_stuff (), и его можно переопределить.
источник
Чтобы ответить на ваш актуальный вопрос, автоматическое создание вызова super.onCreate () - это функция плагина ADT. В java вы не можете напрямую заставить подкласс вызывать супер-реализацию метода afaik (см. Шаблон, описанный в других ответах для обхода). Однако имейте в виду, что в Android вы не создаете экземпляры объектов Activity (или объектов Service) напрямую - вы передаете Intent системе, а система создает экземпляр объекта и вызывает onCreate () для него (вместе с другими методами жизненного цикла). Таким образом, система имеет прямую объектную ссылку на экземпляр Activity и может проверять (предположительно) некоторое логическое значение, для которого установлено значение true в реализации суперкласса onCreate (). Хотя я точно не знаю, как это реализовано, вероятно, это выглядит примерно так:
class Activity { onCreate() { superCalled = true; ... } ... }
И в классе «системного» уровня, который получает намерение и создает из него экземпляр объекта Activity:
... SomeActivitySubclass someActivitySubclassObject = new SomeActivitySubclass(); someActivitySubclassObject.onCreate(); if (!someActivityObject.isSuperCalled()) { Exception e = new Exception(...) //create an exception with appropriate details throw e; }
Я предполагаю, что это, вероятно, немного сложнее, но вы поняли идею. Eclipse автоматически создает вызов, потому что плагин ADT сообщает об этом для удобства. Удачного кодирования!
источник
В Java нет ничего, что заставляло бы вызывать super, и есть множество примеров, когда вы этого не хотите. Единственное место, где вы можете принудительно вызвать super, - это конструкторы. Все конструкторы должны вызывать конструктор суперкласса. Один (конструктор без аргументов) будет вставлен, если вы не напишете его явно, а если конструктора без аргументов нет, вы должны вызвать его явно.
источник
Eclipse просто помогает, напоминая вам, что вы можете вызвать реализацию суперкласса, если хотите.
вы, вероятно, получаете ошибку, потому что вы не делаете что-то необходимое, что делает суперкласс, поскольку вы не вызываете его реализацию.
источник
Eclipse просто помогает вам делать все правильно и избегать исключений.
Из http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle )
источник