2013-02-18 37 views
0

我有两个阶级作为阶级:如何从我在该类中创建的类访问类的变量?

public class A{ 
    ArrayList<Runnable> classBList = new ArrayList<Runnable>(); 
    int x = 0; 

    public A(){ 
     //This code here is in a loop so it gets called a variable number of times 
     classBList.add(new B()); 
     new Thread(classBList.get(classBList.size())).start(); 
    } 
} 

public class B implements Runnable{ 
    public B(){ 

    } 

    public void run(){ 
     //Does some things here. blah blah blah... 
     x++; 
    } 
} 

的问题是,我需要有B类的实例改变A类变量x,创建类B.然而类,我不知道我如何让B班知道它需要改变价值,或者如果可以的话。任何建议如何改变它将不胜感激。谢谢!

+0

这个问题不清楚。你能重构你的问题吗? – 2013-02-18 09:09:55

+0

你是否想用x计算“完成的任务”?你应该考虑同步...见http://www.vogella.com/articles/JavaConcurrency/article.html 3.2节 – Fildor 2013-02-18 09:16:22

回答

3

您需要为B实例提供对A实例的访问权限。有几个方法可以做到这一点:

  1. BA派生和A使数据字段(或存取他们的)protected。我会倾向于回避这个问题。

  2. 使B在其构造函数中接受A实例。

  3. 使B接受在其构造函数中实现某个接口的类的一个实例,并且A实现该接口。

你选择哪个取决于你。我已经给它们大致递减的耦合顺序,其中越松散耦合越好(通常)。

即在代码第三个选项:

public TheInterface { 
    void changeState(); 
} 

public class A implements TheInterface { 
    ArrayList<Runnable> classBList = new ArrayList<Runnable>(); 
    int x = 0; 

    public A(){ 
     //This code here is in a loop so it gets called a variable number of times 
     classBList.add(new B(this)); // <=== Passing in `this` so `B` instance has access to it 
     new Thread(classBList.get(classBList.size())).start(); 
    } 

    // Implement the interface 
    public void changeState() { 
     // ...the state change here, for instance: 
     x++; 
    } 
} 

public class B implements Runnable{ 
    private TheInterface thing; 

    public B(TheInterface theThing){ 
     thing = theThing; 
    } 

    public void run(){ 
     // Change the thing's state 
     thing.changeState(); 
    } 
} 

现在,既AB耦合到TheInterface,但只A耦合到B; B不耦合到A

+0

...其中OP的情况中的“changeState”会做x ++。 – Fildor 2013-02-18 09:14:32

+1

@Fildor:谢谢,是的。我已经编辑过,使其更清晰(并将'x'移回'A'!)。 – 2013-02-18 09:16:28

+0

我想补充一点,那就是x ++不是原子的。我建议使用'volatile'或'AtomicInteger',因为上面的代码是多线程的。 – Fildor 2013-02-18 09:22:05

1

你需要B类内扩展一个类,即:

public class B extends A implements Runnable { 
} 

这台B类为一个类的子类,允许它访问其变量。

+1

不一定。他也可以给B一个A的参考并让A实现X的setter/getter。 – Fildor 2013-02-18 09:09:48

+0

正确 - 我只是认为这是最简单的解决方案(虽然不一定是最好的) – 2013-02-18 09:10:56

1

您需要使类B以某种方式知道类A的哪个实例创建它。 它可以有它的创造者的引用,例如:

public class B implements Runnable{ 
    private A creator; 
    public B(A a){ 
     creator = a; 
    } 

    public void run(){ 
    //Does some things here. blah blah blah... 
    x++; 
    } 
} 

再经过创作者当您从类A构造它:

... 
classBList.add(new B(this)); 
...