86

Activity新しいクラスを作成してからonCreate()メソッドをオーバーライドすると、Eclipse で常に auto added: が追加されるのではないかと思っていましsuper.onCreate()た。これはどのように起こりますか?これを強制する抽象クラスまたは親クラスに Java キーワードはありますか?

スーパークラスを呼び出さないことが違法かどうかはわかりませんが、いくつかのメソッドで、これを行わないと例外がスローされたことを覚えています。これもJavaに組み込まれていますか?それを行うためにいくつかのキーワードを使用できますか?またはどのように行われますか?

4

8 に答える 8

199

これは、サポート アノテーション ライブラリに追加されます。

dependencies {
    compile 'com.android.support:support-annotations:22.2.0'
}

http://tools.android.com/tech-docs/support-annotations

@CallSuper

于 2015-06-09T17:44:07.527 に答える
85

サブクラスに親クラスのロジックを強制的に実行させたい場合、一般的なパターンは次のようなものです。

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()

于 2010-11-18T16:30:26.930 に答える
10

ソースは次のとおりです-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()思います。全くの推測ですが。

于 2010-11-18T16:37:47.683 に答える
9

スーパークラス メソッドも確実に呼び出されるようにしたい場合は、少し工夫する必要があります。

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() にあり、オーバーライドできます。

于 2010-11-18T16:29:17.200 に答える
8

実際の質問に答えるために、super.onCreate() への呼び出しの自動作成は ADT プラグインの機能です。Javaでは、サブクラスにメソッドのスーパー実装を直接強制的に呼び出すことはできません.afaik(回避策については、他の回答で説明されているパターンを参照してください)。ただし、Android では、Activity オブジェクト (または Service オブジェクト) を直接インスタンス化していないことに注意してください。Intent をシステムに渡すと、システムがオブジェクトをインスタンス化し、onCreate() を呼び出します (他のライフサイクル メソッドと共に)。そのため、システムは Activity インスタンスへの直接オブジェクト参照を持ち、(おそらく) onCreate() のスーパークラス実装で true に設定されたブール値をチェックできます。正確な実装方法はわかりませんが、おそらく次のようになります。

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

そして、インテントを受け取り、そこからアクティビティ オブジェクトをインスタンス化する「システム」レベル クラスでは、次のようになります。

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

私の推測では、おそらくそれよりも少し複雑ですが、アイデアはわかります。便宜上、ADT プラグインが指示するため、Eclipse は自動的に呼び出しを作成します。ハッピーコーディング!

于 2012-06-27T23:08:26.340 に答える
4

Java には、スーパーの呼び出しを強制するものは何もありません。また、そうしたくない場合の例もたくさんあります。スーパーの呼び出しを強制できる唯一の場所は、コンストラクターです。すべてのコンストラクターは、スーパークラス コンストラクターを呼び出す必要があります。明示的に記述しない場合は 1 つ (引数なしのコンストラクター) が挿入されます。引数なしのコンストラクターがない場合は、明示的に呼び出す必要があります。

于 2010-11-18T16:22:19.793 に答える
3

必要に応じてスーパークラスの実装を呼び出すことができることを思い出してください。

スーパークラスの実装を呼び出していないため、スーパークラスが行う必要のあることを行っていないため、おそらくエラーが発生しています。

于 2010-11-18T16:22:29.100 に答える
1

Eclipse は、物事を正しく行い、例外を回避するのに役立ちます。

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

派生クラスは、このメソッドのスーパー クラスの実装を呼び出す必要があります。そうでない場合は、例外がスローされます。

于 2011-03-17T00:01:36.297 に答える