2

================================================== =================================================

アップデート:

私の問題は、クラスが実際に互いに通信できることを知らなかったことです。たとえば、2 つのクラスを作成し、プログラム内で各クラスのオブジェクトをインスタンス化してから、実際に 1 つのオブジェクトを別のオブジェクトに渡すことができます。これは私の問題を直接解決しただけでなく、将来の可能性の全世界を開きます.

public class FirstClass {
    int valueToPass = 100;
    void methodToPass(){
    //do stuff
    return;
    }
}
public class SecondClass {
    FirstClass passedInObject;
    int valueFromOtherClass = passedObject.valueToPass;
    return;
    }
}

================================================== =================================================

クラスは、オブジェクトとしてインスタンス化できる属性とアクションの青写真であることを理解しています。内部クラスは別のクラス内で定義された非静的クラスであり、外部クラスのデータにアクセスできることを理解しています。子クラスは、親のデータにアクセスできないクラスを定義する別のファイルであることを理解しています。

これで、Android アプリケーションのメイン アクティビティ クラスができました。私は単純なさいころゲームを作って、すべてのルーズエンドを結びつけるのに役立ちます. 個別の .java ファイルで次の子クラスを定義しました。

ダイススコアカード

5 つの Dice オブジェクトと 1 つの ScoreCard オブジェクトの配列をインスタンス化し、それらのオブジェクトを Android OS のウィンドウの「ビュー」にアタッチしてから、オブジェクト内の set click リスナー メソッドを使用してアクション メソッドをそのビューに割り当てます。オブジェクトは問題なく動作します。サイコロをクリックすると、サイコロを保持したり、保持したり、回転したり、独自のビューを更新したりできます。もちろん、object.value 変数を参照することで、メイン クラスからサイコロの値にアクセスできます。(アクセサは、子クラスの変数と直接対話するよりも優れていると多くの人が推測していることを理解しています。このアプリは、アプリケーションの全体的なフローの概念的なアイデアを固めるためのものです) スコアシートのスロットをクリックすると、スコアを割り当てるスロットとして、そのスロットのハイライトを切り替えます。

これまでのところ、すべてが順調に進んでおり、進行しているすべてのことを理解しています。

ただし、メインのアクティビティ クラスでは、ロール関数を作成し、その関数をロール ボタンのクリック リスナーに割り当てたいと考えています。これは機能しますが、関数をクリック リスナーに割り当てる場合、非 final 変数を参照することはできません。これは、特定のビューのクリック リスナーが View クラスの匿名オブジェクト (匿名クラス?) を実際にインスタンス化し、onclick メソッドをオーバーライドするためです。したがって、別のメソッドで定義された内部クラスから非最終変数を参照することはできません。つまり、クリック リスナーに割り当てる関数にメイン クラスの値を渡すことはできません。理由はわかりませんが、作成したロール関数はメイン クラスの変数に直接アクセスできません。

私の知識には最初のギャップがあり、何十ものチュートリアルを読み、何十ものビデオを見てきましたが、ロール関数が変数を認識できない理由がわかりません。

public mainclass extends otherclass {
      @override 
      otherclass.method {
             // where my application starts
             int a=7;
             roll();
      }

      void roll(){
          int funcVar = a;
          return;
      {
}

Eclipse は、a を解決できないと言っています。

私は機能がそれを見ることを可能にするかもしれない考えを公にしようとしますが、私が変わると

int a=7;

public int a=7;

次に、Eclipseは、公開することはできず、最終的なものであると言います。

これを回避するには、ScoreCard クラスと Dice クラスで行ったように、Roll という新しい子クラスを作成するか、将来他のボタンに使用する ActionButton を作成します。ロール ボタン オブジェクトをインスタンス化し、ビューをオブジェクトに割り当て、クリック リスナーをオブジェクトのメソッドの 1 つに設定できる限り、これはうまく機能します。ただし、これによりロールボタンの機能が MainActivity クラスから RollButton クラスに転送されますが、RollButton クラスはサイコロとスコアカード オブジェクトのデータにアクセスできません。言い換えれば、自分の子クラスが互いに話し合うようにする方法を理解できません。メインクラスは各子クラスに個別にアクセスすることになっていると思いますが、そうであれば、この時点で何をすべきかよくわかりません。

私が考えることができる唯一の解決策は、これらすべての子クラスを同じ子クラス DiceGame に配置し、MainActivity クラスを使用して DiceGame クラスのオブジェクトをインスタンス化し、処理を完全にそのオブジェクトに移すことです。それは機能しますが、クラス内のすべてのメソッドはクラス内のすべてのデータにアクセスできますが、オブジェクト指向プログラミングの目的全体と矛盾しているようです。

最終変数以外の変数にアクセスできない匿名の内部クラスをインスタンス化することによってAndroidアプリのクリックリスナーが割り当てられる方法が原因で、これはすべて混乱していますか、それともJavaアプリケーションが構造化されている方法で重要な概念が欠けているだけですか?

長くなって申し訳ありませんが、短くして問題全体を伝えることはできませんでした。

- - - -編集 - - - - -

    public class MainActivity extends Activity {

public int a=7;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);

            // my application starts here

    Dice[] gameDice = new Dice[6];

    for (int i=1;i<6;i++) gameDice[i]= new Dice();
    for (int i = 1; i<6 ; i++){
        gameDice[i].dieView = (ImageView) findViewById(R.id.die1 + (i-1));
        gameDice[i].setListener();
    }


    int[] slotId = new int[] {R.id.val1,
            R.id.val1,R.id.val2,R.id.val3,R.id.val4,R.id.val5,
            R.id.val6,R.id.valsubtotal,R.id.valbonus,

            R.id.val3k,R.id.val4k,R.id.val5k,R.id.valfh,
            R.id.valsmstr,R.id.valstr,R.id.valdicey,R.id.valtotal
    };


    ScoreCard scoreCard = new ScoreCard();
    scoreCard.NUMBER_OF_SLOTS = slotId.length;
    for (int i=1 ; i<scoreCard.NUMBER_OF_SLOTS ; i++){
        scoreCard.slotView[i]=(TextView) findViewById(slotId[i]);
        if (i!=8 && i!=15) scoreCard.setListener(i);
    }
    scoreCard.initScoreCard();


    rollButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            roll();

        }
    });
}// end of overridden method

void roll(){
//do stuff
int funcVar = a; // can totally see a now that it is higher scope
return;
}

}// クラスの終わり

の範囲を拡大するという提案は、実際に機能しました。ただし、 a は、簡単にするために使用した例にすぎません。インスタンス化したオブジェクトに含まれるデータに実際にアクセスする必要があり、それらをより高いスコープでインスタンス化すると、起動時にアプリケーションが突然終了します。

4

2 に答える 2

2

おそらく、混乱は変数とフィールドの間にあります。フィールドは、オブジェクトに関連付けられているプロパティです。変数は、メソッドのコンテキストにのみ存在します。メソッドが終了すると、変数は消えます。

一方、フィールドは変数とまったく同じように見えますが、フィールドはメソッドの外部で、クラスの「本体」で直接宣言される点が異なります。フィールドとメソッドは同じ階層レベルで宣言されます。Eclipseでそれを見ることができます。「アウトライン」ビューを確認します。

同じ「変数」を読み書きするために複数のメソッドが必要な場合、必要なのはフィールドです。これが明確になることを願っています。

于 2013-11-12T14:38:15.627 に答える