まず、タイトルは同じですが、これはこの質問の重複ではありません。その質問は、本質的に C 関数と同じメソッドを渡すことについて言及していました。特定のオブジェクトに属する必要はありませんでした。その場合、Runnable
orCallable
オブジェクトを渡すことができます。
代わりに、私は次のことを尋ねています: クラス内の特定のメソッドへの参照を渡し、そのメソッドを特定のオブジェクトに対して呼び出すことは可能ですか?
FlowLayout
例として、 Swingの のコードを見ていて、preferredLayoutSize
とのminimumLayoutSize
実装が 1 行を除いてまったく同じであることに気付きました。
public Dimension preferredLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
Dimension dim = new Dimension(0, 0);
int nmembers = target.getComponentCount();
boolean firstVisibleComponent = true;
boolean useBaseline = getAlignOnBaseline();
int maxAscent = 0;
int maxDescent = 0;
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
dim.height = Math.max(dim.height, d.height);
if (firstVisibleComponent) {
firstVisibleComponent = false;
} else {
dim.width += hgap;
}
dim.width += d.width;
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
maxAscent = Math.max(maxAscent, baseline);
maxDescent = Math.max(maxDescent, d.height - baseline);
}
}
}
}
if (useBaseline) {
dim.height = Math.max(maxAscent + maxDescent, dim.height);
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right + hgap*2;
dim.height += insets.top + insets.bottom + vgap*2;
return dim;
}
}
public Dimension minimumLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
boolean useBaseline = getAlignOnBaseline();
Dimension dim = new Dimension(0, 0);
int nmembers = target.getComponentCount();
int maxAscent = 0;
int maxDescent = 0;
boolean firstVisibleComponent = true;
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.visible) {
Dimension d = m.getMinimumSize();
dim.height = Math.max(dim.height, d.height);
if (firstVisibleComponent) {
firstVisibleComponent = false;
} else {
dim.width += hgap;
}
dim.width += d.width;
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
maxAscent = Math.max(maxAscent, baseline);
maxDescent = Math.max(maxDescent,
dim.height - baseline);
}
}
}
}
if (useBaseline) {
dim.height = Math.max(maxAscent + maxDescent, dim.height);
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right + hgap*2;
dim.height += insets.top + insets.bottom + vgap*2;
return dim;
}
}
メソッドは( -番目のコンポーネント)のメソッドをpreferredLayoutSize
呼び出しますが、 のメソッドを呼び出します。私が見る限り、2 つの方法はそれ以外は同じです。 preferredLayoutSize
m
i
minimumLayoutSize
minimumLayoutSize
m
プログラマなら誰でも言うように、コードの重複は悪いことです。ただし、この場合、重複したコードを取り除く方法は明らかではありません。クラスのpreferredLayoutSize
およびminimumLayoutSize
メソッドへの参照を渡し、両方のパブリック メソッドが呼び出すコードを含むプライベート メソッドが必要であることは明らかです。Component
CI では、関数ポインターを使用してそれを行うことができるため、Java でそれを行う何らかの方法が必要であることは理にかなっています。Runnable
orを渡すとCallable
ほとんど機能しますが、どちらも値を返しません。 編集:これは間違っています。のオーバーライドされたメソッドはCallable
値を返し、それが作用するオブジェクトはパラメーターとして渡すことができます。
すべてを入力したので、解決策が思い浮かびます。interface
と呼ばれるメソッドを使用してDimension layoutSize(Component comp)
を記述し、2 つの実装を記述することができます。一方は を返しcomp.preferredLayoutSize()
、もう一方は を返しcomp.minimumLayoutSize()
ます。次に、そのインターフェイスのインスタンスをパラメーターとして取るプライベート メソッドを記述し、それを使用して、コードの適切なポイントで個別のメソッドを実行できます。匿名の内部クラスを使用することもできるため、レイアウト サイズの種類ごとに新しいクラスを作成する必要はありません。ただし、かなり単純な問題の場合は、依然として非常に多くの問題のように思えます。もっと簡単な方法はありますか?