Your SlideShare is downloading. ×
0
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Objc02
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Objc02

512

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
512
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 第11回iPhone輪講 CHAPTER04
  • 2. CHAPTER04 オブジェクトの型と 動的結合
  • 3. 動的結合とは 実際のプログラミングでは様々なクラスのインスタンス を使う事になる ‣ すべてのオブジェクトがid型で表されていると 「どのオブジェクトがどのクラスのインスタンス」か わからなくなりやすい
  • 4. 動的結合とは List4-1
  • 5. 動的結合とは
  • 6. 動的結合 このプログラムは端末から入力された数により 変数objに代入するオブジェクトのクラスが異なるよう になっている クラスA,BはwhoAreYouというメッセージに対応 できる 0を入力すると「I m A」が表示される 1を入力すると「I m B」が表示される
  • 7. 動的結合 クラスNSObjectではwhoAreYouを定義していない ため対応できない 2を入力するとエラーが発生する ‣ しかしコンパイルできてしまう
  • 8. 動的結合 ObjCは『あるオブジェクトで,そのメッセージが処理 できるかどうか,どのように処理されるか』は, オブジェクトへ実際にメッセージを送ったときに 決定される
  • 9. 動的結合 すべてのインスタンスは自分がどのクラスなのか 知っている メッセージを受け取ったときにそれに応じた処理が 実行できる 逆にそのオブジェクトが受け取ったメッセージを 処理できないときにエラーが返る
  • 10. 動的結合 送られてきたメッセージに対応してどのメソッドが 実行されるのかが実行時に決定される方式を 動的結合(dynamic binding)あるいは,動的束縛と 呼ぶ
  • 11. ポリモルフィズム List4-1では変数objに代入されているインスタンスが クラスA,クラスBどちらのものでも同じメッセージに 反応した だが,その反応は代入されているインスタンスに 依存していた
  • 12. ポリモルフィズム 同じメッセージを送っても,レシーバのオブジェクトに 応じて適切なメソッドが選ばれて実行される性質を ポリモルフィズム(polymorphism)と呼ばれる
  • 13. 型としてのクラス クラス名を型として使う 定義したクラスは新しい型として使える オブジェクトは基本的にid型で表す しかし特定のクラスのインスタンスであることを 明示する事もできる
  • 14. クラス名を型として使う あるクラスFooのインスタンスであることを 明示するには という型を用いる事が出来る この型はオブジェクとが代入される変数, メソッドや関数の引数,返り値の型として 普通に使える Foo *
  • 15. クラス名を型として使う 例えば変数の宣言は, これは「オブジェクトはポインタとして 表現されている」ということ Volume *v; MuteVolume *mute;
  • 16. クラス名を型として使う 「オブジェクトがポインタとして表現さている」 代入によって変数v2はv1が指すものと 同じものを指す printf()で出力される値は0でなく1になる Volume *v1, *v2; v1 = [[Volume alloc] initWithMin:0 max:10 step:1]; v2 = v1; [v1 up]; printf(“%dn”, [v2 Value];
  • 17. nil 空のポインタnil ObjCでは何のオブジェクトも表していない (ポインタが実体を何も指していない)ことを 表すのにnilという値を用意している
  • 18. nil nilはid型のポインタで値は0 イニシャライザが初期化に失敗した時に返す値はnil インスタンスオブジェクトを新しく作成するとき メソッドallocはインスタンス変数を0で初期化する id型やその他オブジェクトへのポインタもnilで 初期化する
  • 19. 型の静的なチェック オブジェクトをid型としてでなく,クラス名を明示して 宣言する するとコンパイル時に型チェックが行える 構文上宣言したクラスと,そこに使われる オブジェクトのクラスが一致しない場合警告を 表示する事が出来る
  • 20. 型の静的なチェック ObjCで使われるクラスが確定している場合 クラス名を明示して型宣言を行う事によって メッセージが処理可能かどうかをコンパイル時に チェックできる
  • 21. List4-2 型チェックの実験
  • 22. List4-2 型チェックの実験
  • 23. 型の静的なチェック このプログラムはクラスAとCは独立して定義され, BはAのサブクラスとして定義されている main関数の中で変数をクラス名を使って定義している
  • 24. 型の静的なチェック コンパイルすると以下の警告が表示される クラスCにはwhoAreYouメソッドが無い為 表示されている 型チェックは機能している
  • 25. 型の静的なチェック main関数の中の変数の型を次のように変更し, コンパイルする 警告は出なくなるが,実行するとエラーが返る C *c; id c;
  • 26. 型の静的なチェック メソッドの呼び出し部分を以下のように変更して コンパイルする これで実行できるようになる 実行結果は [a whoAreYou]; [b whoAreYou]; [c whoAreYou]; [a whoAreYou]; [b whoAreYou]; [c printName];
  • 27. 型の静的なチェック 変数aもbもクラスAのインスタンスのとして型が 宣言されている しかし特に警告が出ない クラスAから継承した機能だけ使っている限り クラスBのインスタンスも「Aのインスタンスだ」 と言う顔をして動作させる
  • 28. 型の静的なチェック 次に変数bのメソッド呼び出しを以下のようにする という警告が出るが,問題なく動作する [b whoAreYou]; [b sayHello];
  • 29. 型の静的なチェック 警告を出さないようにするには素直に変数bを クラスBのインスタンスとして宣言すればよいが, 以下のような方法もある 変数bをクラスBのインスタンスとしてキャストし, コンパイラをごまかしている [(B*)b sayHello];
  • 30. 型の静的なチェック 最後に変数aはクラスAのインスタンスだが, 以下のようにキャストしたらどうなるか 実行すると「I m A」と出力される 実行されるメソッドがキャストによって静的に 決まるということはない [(B*)a whoAreYou];
  • 31. プログラミングにおける 型宣言 シグネチャが異なる場合 メッセージセレクタには引数や返り値の型の情報はな いが,セレクタと型情報を合わせたものを シグネチャ(signature)と呼ぶ インタフェースでメソッド宣言に用いる以下のような 形式のことをシグネチャ呼ぶ事がある - (id)cellAtRow:(int)row column:(int)col;
  • 32. プログラミングにおける 型宣言 プログラム内のメソッド呼び出しには メッセージセレクタが書かれているだけで, 引数や返り値の型まではわからない セレクタが同じでも引数や返り値の型が異なる メソッドがあった時はどうなるのか
  • 33. プログラミングにおける 型宣言 次のインタフェースが宣言されていたとする @interface X : NSOBject - (int)value; @end @interface Y : NSObject - (float)value; @end @interface Z : X - (const char *)value; @end
  • 34. プログラミングにおける 型宣言 このとき以下のメッセージはコンパイルできてしまう 実際どんな値が返されるコードが生成されるのかは, コンパイラ任せになってしまう id obj; ... a = [obj value];
  • 35. プログラミングにおける 型宣言 以下のような場合どうなるか この場合変数barは期待通りの結果が得られる 変数fooにはクラスZのインスタンスが代入されてい る可能性がある 実行時に誤作動するかもしれない X *foo; Y *bar; ... a = [foo value]; b = [bar value];
  • 36. プログラミングにおける 型宣言 レシーバや引数となるオブジェクトの型が実行時に 決まってもよいとする以上,メッセージのシグネチャが 何通りも存在していたのでは正しくコンパイルできない
  • 37. プログラミングにおける 型宣言 結局,ObjCにおいては基本的に, 『同じセレクタを持つメッセージは引数や返り値の型 (シグネチャ)を同じにすべきである』 と,結論づける事が出来る
  • 38. クラスの前方宣言 あるクラスのインタフェース部を記述する際 インスタンス変数の型やメソッドの返り値, 引数の型として別のクラスを指定することがある このような場合その型名がクラスである事を どうやってコンパイラに知らせるのか?
  • 39. クラスの前方宣言 1つの方法は,そのクラスのインタフェース部を含む ヘッダファイルをインポートする #import <Foundation/NSObject.h> #import “Volume.h” //Volumeクラスのインタフェース部をインポート @interface AudioPlayer : NSObject { Volume *theVolume; ... } - (Volume *)volume; ...
  • 40. クラスの前方宣言 ヘッダファイルにはクラス名の定義以外の様々な情報が 書かれていることもある コンパイル時に必要以上に処理が重くなる事も 考えられる クラス名を型として使うだけなら,「クラス名である」 という以上の情報は必要ない
  • 41. クラスの前方宣言 以下のような書き方が出来る @classというコンパイラ指示子で 「Volumeという識別子はクラス名である」という 事を宣言している これをクラス名の前方宣言(forward declaration) と呼ぶ #import <Foundation/NSObject.h> @class Volume; //Volumeというクラスを使う事を宣言 @interface AudioPlayer : NSObject ...
  • 42. クラスの前方宣言 @classの後には「,」で区切って複数個書く事が出来る 末尾には「;」を置く @classは何個でも書く事が出来る @class NSString, NSArray, NSMutableArray; @class Volume, MuteVolume
  • 43. インスタンス変数の 情報隠蔽 インスタンス変数へのアクセス これまでのプログラムの例ではインスタンス変数に アクセスできるのは保持しているオブジェクト自体 ObjCでは基本的にはオブジェクトの外から インスタンス変数へのアクセスを許可していない
  • 44. インスタンス変数への アクセス しかし,クラスAのメソッド定義の中からクラスAの self以外のインスタンスが持つインスタンス変数には 直接アクセスできる アクセスできるかのチェックはコンパイル時に 行われる
  • 45. インスタンス変数への アクセス インスタンス変数にアクセスするには,そのインスタン スオブジェクトが静的に(クラス名を型として使って) 型宣言されていなければならない
  • 46. インスタンス変数への アクセス インスタンスオブジェクトobjが持つ インスタンス変数myvarにアクセスする この記法はポインタで構造体のメンバにアクセスする 場合と同じ obj -> myvar
  • 47. インスタンス変数への アクセス 次のプログラムは色の三原色を表現したクラスで 2つの色の中間の色を計算する機能が付いている
  • 48. インスタンス変数への アクセス 三原色クラスのインタフェース部 (RGB.h)
  • 49. インスタンス変数への アクセス 三原色クラスの実装部 (RGB.m)
  • 50. インスタンス変数への アクセス 三原色クラスの実装部 (RGB.m)
  • 51. インスタンス変数への アクセス 三原色クラスをテストするmainプログラム (rgbmain.m)
  • 52. インスタンス変数への アクセス メソッドblendColorの中で引数のオブジェクトに対して 「->」を使ってインスタンス変数を直接参照している 引数が同じクラスのインスタンスなので この方法でアクセス可能 他のクラスのインスタンス(スーパークラスのイン スタンスであっても)この方法では参照できない クラスを使って型が宣言されていない場合でも アクセスできない
  • 53. インスタンス変数の可視性 インスタンスオブジェクトが持つインスタンス変数には 外部から直接アクセスしない方がよい どうしてもアクセスしたい場合許可する方法がある
  • 54. インスタンス変数の可視性 インスタンス変数の外部への見せ方(見せるかどうか, 範囲はどこまでか)を可視性(visibility)と呼ぶ ObjCではインスタンス変数に3種類の可視性を指定 できる
  • 55. インスタンス変数の可視性 @private 宣言したクラス内のみでアクセス可能 サブクラスからはアクセスできない 同じクラスのインスタンスなら,メソッド内で ->演算子を使ってアクセスできる
  • 56. インスタンス変数の可視性 @protected 宣言したクラス,およびそのサブクラス内で アクセス可能 同じクラスのインスタンスなら,メソッド内で ->演算子を使ってアクセスできる 通常何も指定していないインスタンス変数は このモード
  • 57. インスタンス変数の可視性 @public どこからでも,構造体のメンバのようにして 参照できる
  • 58. インスタンス変数の可視性 @private @protected @public 同じクラス内 ○ ○ ○ 同じクラス内で->を使って ○ ○ ○ サブクラスから ○ ○ サブクラスから->を使って ○ どこからでも ○
  • 59. インスタンス変数の可視性 可視性の指定はクラスのインタフェース部の インスタンス変数の宣言部分で行う インスタンス変数の宣言の先頭,あるいは宣言と宣言 の間(;の後)に3つのコンパイラ指示子のいずれかを 記述できる
  • 60. インスタンス変数の可視性 コンパイラ指示子の可視性の指定は, その位置からインスタンス変数の宣言が終わるまで 別のコンパイラ指示子が出現するまで その間のインスタンス変数に対して有効になる
  • 61. インスタンス変数の可視性 コンパイラ指示子の出現順序に制限は無い また,何回現れても構わない
  • 62. インスタンス変数の可視性 @interface TableOfColors : HashTable { id delegate; //protected @public BOOL empty; //public @private id cache; //private int cache_entries; //private @protected int entries; //protected } ... @end
  • 63. つづく(多分)

×