2

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

更新:

我的问题是我不知道类确实可以相互交流。例如,您可以创建 2 个类,在程序中实例化每个类的一个对象,然后将一个对象实际传递给另一个对象。这不仅直接解决了我的问题,还为未来打开了一个充满可能性的世界。

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 listener 方法为该视图分配一个操作方法。这些对象完美地工作。我可以点击骰子,他们将持有和取消持有自己,滚动并更新他们自己的观点。我当然可以通过引用它们的 object.value 变量从我的主类中访问骰子的值。(我知道许多人认为访问器优于直接与子类的变量直接交互,这个应用程序只是为了巩固应用程序整体流程的概念思想)我可以单击记分表上的一个插槽,它会切换突出显示该插槽作为分配分数的插槽。

到目前为止一切顺利,一切都很好,我了解正在发生的一切。

但是,在我的主要活动类中,我现在想创建一个滚动函数,并将该函数分配给滚动按钮的单击侦听器。但是,当将函数分配给单击侦听器时,您不能引用任何非最终变量,因为给定视图的单击侦听器实际上实例化了 View 类的匿名对象(匿名类?)并覆盖 onclick 方法它自己的,因此您不能从另一个方法中定义的内部类引用任何非最终变量。换句话说,您不能将分配给单击侦听器的函数传递给主类中的任何值,尽管我不明白为什么,但我创建的滚动函数无法直接访问主类的变量。

第一个知识差距,我看了几十个教程,看了几十个视频,不知道为什么我的roll函数看不到变量。

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

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

Eclipse 说无法解决。

我尝试公开思考可能允许函数看到它,但如果我改变

int a=7;

public int a=7;

然后 Eclipse 说它不能公开,只能是最终的。

解决此问题的一种方法是创建一个名为 Roll 的新子类,或者可能是 ActionButton 以便将来将其用于其他按钮,就像我对 ScoreCard 和 Dice 类所做的那样。这很有效,因为我可以实例化一个滚动按钮对象,为该对象分配一个视图,然后将单击侦听器设置为该对象的方法之一。但是,这会将滚动按钮的功能从 MainActivity 类转移到 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 范围的建议确实奏效了。但是,a 只是为了简单起见我使用的一个示例。我真的需要访问我实例化的对象中包含的那些数据,如果我在更高的范围内实例化它们,应用程序会在启动时突然结束。

4

2 回答 2

2

变量可以有不同的范围

public class MyClass {

   static int a; // variable bound to class MyClass, seen from all instances
   int b; // variable bound to instance, each instance of MyClass has its own value

   public void foo(int c) { // parameter variable: local
      int d; // local variable
   }
}

方法中的局部变量仅在同一方法调用中可见(因此每次调用 foo() 时,都会使用新的局部变量)。

可以通过将值存储在实例或类变量(全局变量)中来间接传递值,但这很丑陋且容易出错。更好的变体是将值作为方法参数传递,这适用于多个调用和多个线程,并且消除了使用全局变量传递值时的副作用。

在您的示例中,只需将 a 的值传递给您的方法:

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

      void roll(int funcVar){
          // funcVar is whatever value was passed, here: 7
          return;
      {
}
于 2013-11-12T14:41:26.720 回答
2

也许混淆是在变量和字段之间。字段是与对象关联的属性。变量仅存在于方法的上下文中。当方法结束时,变量消失。

另一方面,字段看起来与变量完全相同,只是字段是在任何方法之外直接在类“body”上声明的。字段和方法在同一层次上声明。您可以在 Eclipse 上看到这一点。检查“大纲”视图。

如果你需要几种方法来读写同一个“变量”,那么你需要的是一个字段。我希望这可以澄清。

于 2013-11-12T14:38:15.627 回答