Подтвердить что ты не робот

Как заставить производный класс вызвать супер метод? (Как и Android)

Мне было интересно, создавая новые классы Activity, а затем переопределяя метод onCreate(), в eclipse всегда добавляю auto: super.onCreate(). Как это произошло? Есть ли ключевое слово java в абстрактном или родительском классе, что заставляет это?

Я не знаю, незаконно ли вызывать суперкласс, но я помню, в некоторых методах, что я получил исключение, за которое не делал этого. Является ли это также встроенным в java? Можете ли вы использовать какое-то ключевое слово для этого? Или как это сделать?

4b9b3361

Ответ 1

Здесь источник Activity#onCreate() - это почти все комментарии (original - см. строку ~ 800):

/**
 * Called when the activity is starting.  This is where most initialization
 * should go: calling {@link #setContentView(int)} to inflate the
 * activity 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() для вас. Это, однако, общее предположение.

Ответ 3

Если вы хотите заставить подклассы выполнять логику родительского класса, общий шаблон выглядит примерно так:

public abstract class SuperClass implements SomeInterface
{
    // This is the implementation of the interface method
    // Note it 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 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().

Ответ 4

Чтобы ответить на ваш реальный вопрос, автосоздание вызова super.onCreate() является функцией плагина ADT. В java вы не можете напрямую заставить подкласс назвать супер-реализацию метода afaik (см. Шаблон, описанный в других ответах для обхода). Однако имейте в виду, что в Android вы не создаете объекты Activity (или объекты службы) напрямую - вы передаете Intent системе, и система создает экземпляр объекта и вызывает onCreate() на нем (наряду с другими методами жизненного цикла). Таким образом, система имеет непосредственную ссылку на объект экземпляра Activity и может проверить (предположительно) некоторый логический параметр, который установлен в true в реализации суперкласса onCreate(). Хотя я точно не знаю, как это реализовано, вероятно, это выглядит примерно так:

class Activity
{
  onCreate()
  {
    superCalled = true;
    ...
  }
  ...
}

И в классе уровня "system", который получает Intent и создает экземпляр объекта Activity из него:

...
SomeActivitySubclass someActivitySubclassObject = new SomeActivitySubclass();
someActivitySubclassObject.onCreate();
if (!someActivityObject.isSuperCalled())
{
  Exception e = new Exception(...) //create an exception with appropriate details
  throw e;
}

Мое предположение, вероятно, немного сложнее, чем это, но вы получаете идею. Eclipse автоматически создает вызов, потому что плагин ADT сообщает об этом, как удобство. Счастливое кодирование!

Ответ 5

Если вы хотите абсолютно убедиться, что метод суперкласса также вызывается, вы должны немного обмануть: не разрешать перезаписывать суперкласс-метод, но он вызывает переопределяемый защищенный метод.

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(), которая может быть переопределена.

Ответ 6

В Java нет ничего, что принудительно вызывает супер, и есть много примеров, когда вы не захотите. Единственное место, где вы можете принудительно вызвать супер, - это конструкторы. Все конструкторы должны вызывать конструктор суперкласса. Один (конструктор без аргументов) будет вставлен, если вы не будете писать его явно, а если нет конструктора без аргументов, вы должны явно его вызывать.

Ответ 7

Eclipse просто полезен, напоминая вам, что вы можете назвать реализацию суперкласса, если хотите.

вы, вероятно, получаете сообщение об ошибке, потому что вы не делаете что-то необходимое для суперкласса, поскольку вы не вызываете его реализацию.

Ответ 8

Eclipse просто помогает вам делать все правильно и избегать исключений.

Из http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle)

Производные классы должны переходить к реализации суперкласса этого метода. Если они этого не сделают, будет выбрано исключение.