Objective-C クラスの継承における、メソッドの複雑な呼び出し.

Posted on 11/03/2013 by admin in Objective-C

自分のメソッドへアクセスする、”self”変数の使い方

前回、「super」を使ってスーパークラスのメソッドを呼び出す方法を紹介しました。これと同様に「self」変数を用いれば自分のメソッドへアクセスすることができます。

「 [ self (メソッド名)]; 」

しかし、この方法を用いてメソッドを呼び出す際には、注意しなければならない点があります。次の図を見てください。

inheritance6

今、クラスAを継承したクラスBと、クラスBを継承したクラスCを想定します。また、クラスBはmethod1とmethod3を上書きし、クラスCはmethod2を上書きしています。

クラスBのmethod3の中身は、先ほどの”self”変数を用いて自身のmethod1とmethod2を呼び出しています。

クラスBからインスタンスを生成し、このインスタンスが①のようにmethod3を実行したとすると、まずmethod3はself変数を用いて、②のように自分のmethod1を呼び出します。

その後method2を呼びだそうとしますが、自分にはその定義が無いので、スーパークラスのmethod2を③のように呼び出します。

では次のようなケースではどのようにプログラムは処理されるのでしょうか。

inheritance7

 

クラスCから生成したインスタンスが①のようにmethod3を実行したとします。method3はクラスCで上書きされてないので、定義がありません。したがって、スーパークラスのクラスBのmethod3を実行します。

ここでmethod3はselfを用いてmethod1を呼び出していますが、ここでのselfは決してクラスBではありません。selfは自分自身、つまりクラスCのインスタンスを指しているのです。

元々はクラスBのmethod1を意図していたはずですが、ここでプログラムはまず②のようにクラスCのmethod1を見に行きます。

幸運にもクラスCにはmethod1の定義が書かれていないので、もう一度スーパークラス、すなわちクラスBのmethod1に戻ってきています。

そしてmethod2を今度は呼び出しています。この場合はどうでしょうか。ここでもselfを使って呼び出していますので、プログラムはクラスCインスタンスのmethod2だと思い込み、③のように呼び出します。そして、今度はmethod2の定義を発見するので、クラスCのmethod2を実行します。

クラスBのmethod2を意図していたはずが、クラスCのmethod2に起き変わってしまっています。

これは他のメソッドを定義し直すしか回避する方法がありません。このように継承関係の中で、selfやsuperを用いた呼び出しをする場合は、注意しないと予期せぬ動作を起こす可能性があります。

 

 

Share on Facebook

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">