2013-02-18 39 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)); 
...