Objective-C のクラス構成 質問:クラス変数を継承することはできるのでしょうか?

StackOverflow https://stackoverflow.com/questions/1972727

  •  21-09-2019
  •  | 
  •  

質問

Objective-C の感覚をつかむために、私は とても ココアを含まない基本的な接続 4 ゲーム。

私のプログラムには 3 つのモジュールがあります。

  • "ゲーム":ボード情報を保持する配列が含まれます。main 内で作成され、ターンを担当するオブジェクト。Player オブジェクトと Computer オブジェクトはこのモジュール内に存在します。
  • "プレーヤー":プレイヤーの駒を優先列に挿入する関数を保持します (このモジュールはカプセル化の目的でのみ存在します)。
  • "コンピューター":現在のボード設定に基づいて、コンピューターが移動する場所を決定し、その場所にピースを配置する関数を保持します。

理想的には、Player クラスと Computer クラスが同じインスタンスを編集できるようにしたいと考えています。 pieceLoc これはある種の継承を通じてゲーム内に存在しますが、これを行う方法がわかりません。

私が現在考えていることの抜粋は次のとおりです。
// startGame exists within the "Game" module

char *pieceLoc[42]; // This is a *temporary* global var. I'm still learning about
                    // the best way to implement this with class and instance 
                    // methods. This is the array that holds the board info.

-(void) startGame {
 Player   *player   =[[Player alloc] init]; // player's symbol = 'X'
 Computer *computer =[[Computer alloc] init]; // computer's symbol = 'O'

 int i = 0;
 while ([game hasPieceWon: 'X'] == NO && [game hasPieceWon: 'O'] == NO) {
  //function for player move

      if ([game hasPieceWon: 'X'] == NO) {
      //function for computer move
      } 
  }
 if ([game hasPieceWon: 'X'] == YES)
   // Tell the player they've won 
 else
  // Tell the player the computer has won.

}

プレーヤーとコンピューターの移動に使用される関数は、何らかの方法で配列へのアクセスを取得する必要がある関数です。 pieceLoc (クラスとクラスについて詳しく学べば、将来的にはインスタンス変数として存在する予定です。インスタンスメソッド)。 pieceLoc 現在、関数パラメータを介して渡す必要がある場合に備えて、char * として存在します。

これは私が OOP についてどのように考えているかというかなり単純な問題であるように感じますが、午後のほとんどを検索したにもかかわらず、探していることに対する答えを見つけることができませんでした。私が集めたものによると、私の質問はクラス構成に関するものですが、Objective-C に関する適切なリソースが見つかりませんでした。

それで、もう一度:の単一インスタンスを渡す方法を探しています pieceLoc 「親クラス」内に存在するゲームを 2 つの「子クラス」に接続します。 pieceLoc 直接操作できる それなし 追加のパラメータを使用します。

配列をパラメータとして渡すことが最終的により慣用的なことになる場合、Objective-C で参照による受け渡しがどのように機能するかの例を得ることができるでしょうか?

助けてくれてありがとう!

役に立ちましたか?

解決

あなたはおそらくすでに考え出してきたように、

、Objective-Cのは、本当にあなたがスーパークラスから継承することを「クラス変数」を持っていません。

は一つの方法は、あなたがこのようなものになるだろうグローバル変数を持っている必要はありませんことを、このようにを構築するためにます:

あなたはプレーヤーのそれぞれに、および取締役会への参照を保持しているゲームのオブジェクトを持っています。プレイヤーは、いずれかのそれぞれは、理事会を参照して初期化。 (ゲームで)あなたのstartGame方法は、このようなコードを持つことになります:

board = [[Board alloc] init];
player = [[Player alloc] initWithBoard: board];
computer = [[ComputerPlayer alloc] initWithBoard: board];
ボードクラスでは、あなたは、ボードの状態を照会するためのメソッドを持って行動を起こす、動きが合法であるかどうかを判断し、プレイヤーが獲得しているかもしれないかと思います(ゲームのルール関連ロジックかかわらず)ゲームに行くかもしれない。

プレーヤーとComputerPlayerでinitWithBoard方法では、あなただけのボードのインスタンスを保持し、各プレイヤーが作ることを決定した動きを伝えるためにそれを使うだろう。ゲームは、移動の順序を確立し、任意のグローバル状態を追跡します。プレーヤーとComputerPlayerは、ゲームの終了時に解放されたとき、彼らは彼らのdeallocメソッドでボードへの参照を解放したい。

他のヒント

のObjective-Cは、(彼らは単に静的変数を使用してシミュレートしている)それ自体はクラス変数を持っていないので、あなたが同じソースファイル/コンパイル単位でメソッドを定義する場合、子クラスのみが直接静的グローバルにアクセスすることができます。これは、他のベストプラクティス(コンパイル単位ごとに1つのクラス定義を)破ります。アクセスクラスのフィールドへの通常のアプローチは、アクセサを使用することです。

この場合は、注意してくださいあなたはカップルは、あまりにもクラスををしていませんしっかり。メソッドパラメータまたはプロパティとして、Aを参照してより柔軟であるか否か、Player(コンピュータもプレイヤーのようPersonは、より良い名前かもしれない)とComputerに(オブジェクトではなく、アレイなど)ボードを通過グローバルまたは別のクラスの静的メンバに。プレイヤオブジェクトが場所に、そしてどこ作品を配置する場所をボードに伝える場所を決めます。また、ゲームはプレイヤーにボードの読み取り専用バージョンを渡します。プレイヤーの配置方法は、どこの部分を配置する位置を返します。一つには、デカップリングおよびボード・オブジェクトを使用して不正行為を防ぐことができます。彼らは自分のターンに複数のピースを配置することができます、自分のプレイヤークラス注入誰かを想像してみてください。もう一つは、間接それはそれが簡単に(オブジェクト間のメッセージは、ローカル・オブジェクトに透明なプロセスでのネットワークメッセージになる)ネットワークサポートを追加することができます。

のプレイヤーが作成される場所についても考えてみてください。それは何か他のものを持っている選手を作成し、startGameメソッドに渡すために多くの意味をなすかもしれません。プレイヤーは、たとえば、トーナメントに出場し、プレイヤーは、このように単一のゲームよりも長く存在するために必要なオブジェクト場合、これは理にかなってます。

はクラスの組成物は、1つのオブジェクトがメンバとして別のものを有することをいいます。 Cは、例えば、継承をサポートしていますが、巣の構造体をさせませんでした。これは、そのクラスの組成物である、というのがもう一つの方法は、継承は関係の「-です」についてですが、関係「-ている」についてです。プレイヤーのクラスは、例えば、各用途の場所片へのボードへのポインタを、持っている可能性があります。

のObjective-Cも参照渡していません。代わりに、ポインタを使用します。

また、必ずあなたのゲームのハンドルタイを作ります。あなたはこれを実現するためにゲームループを簡素化することができます。擬似コードでは、

// nextPlayer returns 'nil' if game is over (win or tie)
while currPlayer := [game nextPlayer]:
    // player will tell board where to place piece
    [currPlayer move]

それともます:

// nextPlayer always returns a valid player
while currPlayer := [game nextPlayer]:
    // player's method returns what and where to place
    [self place:[currPlayer move] for:currPlayer]
    // explicitly test for game end, which includes wins & ties
    if [game isOver]:
        break
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top