1

JDialog と JFrameの 2 つのクラスがあります (以下を参照)。ここで、いくつかの追加機能を取得したいと考えていますが、コードを 2 回記述することなく、2 つのクラスの両方でコードを拡張できるようにしたいと考えています。それを行う方法はありますか?

java.awt.Window » java.awt.Dialog » javax.swing.JDialog  
java.awt.Window » java.awt.Frame » javax.swing.JFrame

(PS: 実際には、 のソース コードを「書き直して」、java.awt.Window追加の機能を追加したいと考えています。それが不可能であることはわかっていますが、それは「解決策」になります。そうすると、JDialog と JFrame の両方が新しいメソッド。)

例:
メソッド を追加してmoveWindowToMagicPositionOnScreen()、ウィンドウを画面上の使いやすい位置に移動するとします。これは単なる例です。JDialogメソッドを と の両方に適用したいJFrame。継承を使用して、たとえばMagicJDialogと などの 2 つのクラスを記述し、それぞれがまったく同じMagicJFrame方法でメソッドを実装する必要があります。moveWindowToMagicPositionOnScreen()まあ、それはかなり冗長です。そのため、コードを 2 回記述したくありません。何らかの方法で、あるクラスが他のクラスのコードを使用することを望みます

4

4 に答える 4

1

他のいくつかが示唆しているように、継承よりも構成を優先します。ただし、メソッドに共通のインターフェースを作成できます。

public interface Magic {
    void moveWindowToMagicPositionOnScreen();
}

ウィンドウを移動するコードがまったく同じである場合は、デリゲートクラスを作成します。

public class MagicDelegate implements Magic {

    public void moveWindowToMagicPositionOnScreen() {
        // TODO implement logic
    };
}

次に、2つのクラスに次Magicを使用してインターフェイスを実装させますMagicDelegate

public MagicJDialog implements Magic {

    private MagicDelegate magicDelegate;   // TODO instantiate

    public void moveWindowToMagicPositionOnScreen() {
        magicDelegate.moveWindowToMagicPositionOnScreen();
    }
}

public MagicJFrame implements Magic {

    private MagicDelegate magicDelegate;   // TODO instantiate

    public void moveWindowToMagicPositionOnScreen() {
        magicDelegate.moveWindowToMagicPositionOnScreen();
    }
}

MagicDelegateちなみに、ウィンドウを移動するコードは部分的にしか同じではありません。クラスを無視するか、共通の部分を含むテンプレートクラスを作成するかを選択できます。

public abstract MagicTemplate implements Magic {

    public moveWindowToMagicPositionOnScreen() {
        // common logic
        implementationSpecificLogic();
        // more common logic  
    }

    protected abstract void implementationSpecificMethod();
}

これで、MagicJDialogクラスとクラスはMagicJFrameクラスを拡張してメソッドMagicTemplateを実装できます。implementationSpecificLogic()

于 2012-06-30T06:00:37.943 に答える
1

残念ながら、Java は mixin をサポートしていません。ここで採用する最も簡単で明確なアプローチは、合成を使用することです。この場合、ラッパーを 2 回記述するだけで済みますが、実際の実装は 1 つの場所に存在します。

于 2012-06-30T04:47:01.223 に答える
1

インターフェイス / デリゲート / コンポジションのアイデアは、おそらく「最もクリーン」です。しかし、受け入れられ、ほぼ間違いなくより単純な代替手段は、静的メソッドを使用してユーティリティ クラスを作成することです。

public static moveWindowToMagicPositionOnScreen(Window window) {
  // calculate new x and y
  window.setLocation(x, y);  // or perhaps setBounds()...
}

実際には、計算ロジックを別のメソッド () に入れることになるでしょうcomputeMagicPositionOnScreen。理にかなっている場合 (そうでない場合もあります)、この静的ユーティリティ クラスは、実際には「実際の」(静的ではない) クラスである可能性があります。たとえば、MagicPositionCalculator は、複数のインスタンスを持つ可能性があります。たとえば、各画面ごとに 1 つ、非常に大きな画面用に 1 つ、パワーユーザーなど...

于 2012-06-30T06:16:00.090 に答える
0

これを試して、

DRY (Don't Repeat Yourself)設計原則と部分的にLSP を適用したいと思います。(Liskov substitution Principle)あるメソッドをクラスに格納し、他の 2 つのクラスからこのメソッドを使用する場合は、継承よりも構成優先することをお勧めします。不要なメソッドを継承せずに、目的のメソッドを使用できるようになるからです。

于 2012-06-30T05:42:14.727 に答える