2016-08-27 3 views
0

静的に型定義された言語に関しては、何かが足りないと感じています。私がかなり多くの場合、perl way backを使用しただけでは、呼び出す関数をオブジェクトに伝えることができる多くの方法がありました。メソッドリファレンスをオブジェクトコンストラクタに渡す

は今、私はJavaでだと、私は、一般的なButtonクラスを持って、私は簡単に流行っ

に似た何かを行うことができますどのように見ることができません。これは、実際に使用されるすべてのボタンによってサブクラス化されます。クリックされると呼び出すメソッドが異なります。

クリックしたときに呼び出すメソッドへの参照を渡す方法がないので、すべてのボタンに1つのクラスを使用できますか?現時点では

、私はこのようなボタンを作成:

// Specifically using the subclass that sets "firemode" to "close" 
FiremodeClose fc = new FiremodeClose(Settings.ui_panel_start, Settings.ui_panel_row_firemode, game); 
painter.addSelectionButton(fc); 
clickTracker.addSelectionButton(fc); 

このofcourseのは、サブクラスの無数の、唯一の配置、ラベル/グラフィックス、およびメソッド呼び出しが異なる各1をcouses。それは次のように何かをするより理にかなって:

// Generic button, the method that sets "firemode" is somehow passed as arguement to the contsructor. 
Button fc = new Button(&referenceToFunctionToCallWhenClicked, otherArguementsEtc); 
painter.addSelectionButton(fc); 
clickTracker.addSelectionButton(fc); 

私が言ったように、私は何かが欠けする必要があります感じて、それはこのように私はと離れるせ、これを達成する方法がなければならないことを意味しますので、サブクラスのない1つのButtonクラスのみです。

class MyButton { 
    private final Runnable action; 

    public MyButton(Runnable action) { 
     this.action = action; 
    } 
    ... 
} 

を、ボタンがクリックされたときにaction.run()を呼び出します。

+2

これはインターフェイスのためのものです。 Java 8とGroovyは、このようなユースケースのインラインインタフェース実装を簡単にします。 – chrylis

+0

^^^それと、匿名のクラスも見てください。 –

+0

@chrylisそれがインターフェイスのためのものなら、私はそれらの意図された目的以外の何かのためにそれらを使用しているに違いありません。私はこのためのいくつかのコード例を含む答えを見たいと思う。 – Jarmund

答えて

1

それがどんなインターフェースのためのものなのか、私は意図した目的以外の何かのためにそれらを使っていたに違いない。私はこのためのいくつかのコード例を含む答えを見たいと思う。

あなたButtonsだけSwing doesように、observer patternを実装してもらいます。次に、スイングのActionListenerインターフェイスを使用することも、Runnableを使用することもできます。自分自身をロールバックする:

// Your interface. 
public interface MyButtonListener { 
    public void buttonClicked(); 
} 

// Somewhere else: 
Button fc = ...; 
fc.addButtonListener(new MyButtonListener() { 
    @Override public void buttonClicked() { 
     // do stuff here 
    } 
}); 

// And in your Button have it simply iterate through all of its registered 
// MyButtonListeners and call their buttonClicked() methods. 

これを実装する方法はほかにもたくさんあります。

public class MyUI implements ThingThatCaresAboutButtons { 
    @Override public void buttonClicked (Button button) { 
     if (button == theOneButton) { 
      // do whatever 
     } else if (button == theOtherButton) { 
      // do whatever 
     } 
    } 
} 

とボタンを作成:次に、あなたのより高いレベルのUIロジックは、のようなものにしている

public interface ThingThatCaresAboutButtons { 
    public void buttonClicked (Button button); 
} 

theOneButton = new Button(theUI, ...); 
theOtherButton = new Button(theUI, ...); 

たり、それらを持ってたとえば、あなたもような何かを行うことができますコンストラクタで渡される単一のオブジェクトの代わりにリストを維持する。または何でも。

この猫には無限の方法がありますが、うまくいけば、ここでインスピレーションを得ることができます。 Swingの動作を確認してください。

1

あなたは、例えばRunnableを使用することができます。

ボタンを作成するときに、voidの戻り値の型を持つ限り、reference to a methodを渡すことができます。引数はありません。

Button fc = new Button(EnclosingClass::methodToCall, otherArguementsEtc); 

他のインタフェースをさまざまなメソッドシグネチャに使用できます。

あなたがメソッド参照およびラムダの両方を使用できるJava 8で
1

class Button { 
    Button(Runnable function) { 
    } 
} 
Button b1 = new Button(() -> System.out.println("works!")); 
Button b2 = new Button(System::gc); 

あなたは、Java < 8で同様のことを行うことができますが、それは匿名クラスとより冗長です:

Button b3 = new Button(new Runnable() { 
    @Override 
    public void run() { 
     System.out.println("works!"); 
    } 
}); 
関連する問題