【问题标题】:Functions with different signatures, but the same body具有不同签名但主体相同的函数
【发布时间】:2018-12-13 12:10:57
【问题描述】:

考虑一个类

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ShortcutButton extends JButton {
    public ShortcutButton(String text, KeyStroke[] keyStrokes, ActionListener actionListener) {
        super(text);
        addActionListener(actionListener);
        addShortcut(keyStrokes);
    }
    public ShortcutButton(String text, KeyStroke keyStrokes, ActionListener actionListener) {
        super(text);
        addActionListener(actionListener);
        addShortcut(keyStrokes);
    }
    public ShortcutButton(String text, String[] keyStrokes, ActionListener actionListener) {
        super(text);
        addActionListener(actionListener);
        addShortcut(keyStrokes);
    }
    public ShortcutButton(String text, String keyStrokes, ActionListener actionListener) {
        super(text);
        addActionListener(actionListener);
        addShortcut(keyStrokes);
    }

    public void addShortcuts(KeyStroke[] keyStrokes) {
        for (KeyStroke keyStroke : keyStrokes) {
            addShortcut(keyStroke);
        }
    }
    public void addShortcuts(String[] keyStrokes) {
        for (String keyStroke : keyStrokes) {
            addShortcut(keyStroke);
        }
    }
    public void addShortcut(String keyStroke) {
        addShortcut(KeyStroke.getKeyStroke(keyStroke));
    }
    public void addShortcut(KeyStroke keyStroke) {
       //some code here
    }
}

如您所见,ShortcutButton() 构造函数和addShortcuts() 函数具有不同的签名,但主体相同。有没有一种很好的方法可以缩短这段代码,以免在四个不同的函数中复制粘贴相同的代码?

【问题讨论】:

  • 也许你能做的最重要的事情就是删除代码。反复进行“有用的”重载是没有帮助的。 (也“更喜欢组合而不是继承”(或静态方法而不是继承),但这在 GUI 编程中似乎是一个失败的原因。)

标签: java overloading constructor-overloading


【解决方案1】:

如果对参数重新排序并使用可变参数,则可以将它们简化为两个构造函数:

public ShortcutButton(String text, ActionListener actionListener, KeyStroke... keyStrokes) {
    super(text);
    addActionListener(actionListener);
    addShortcuts(keyStrokes);
}
public ShortcutButton(String text, ActionListener actionListener, String... keyStrokes) {
    super(text);
    addActionListener(actionListener);
    addShortcuts(keyStrokes);
}

如果您有将String[] 转换为KeyStroke[] 的方法,则可以进一步缩短代码:

public ShortcutButton(String text, ActionListener actionListener, KeyStroke... keyStrokes) {
    super(text);
    addActionListener(actionListener);
    addShortcuts(keyStrokes);
}
public ShortcutButton(String text, ActionListener actionListener, String... keyStrokes) {
    this(text,actionListener,getShortCuts(keyStrokes));
}

【讨论】:

  • 注意那些空数组!我建议检查长度是否为>=1
  • @MarkJeronimus 好点,虽然这可能是addShortcuts(keyStrokes) 的责任(该方法也应该检查 OP 原始代码中的空数组)。
【解决方案2】:

除了其他答案之外,您还可以使用一个技巧,通过添加私有构造函数,至少将 addActionListener(actionListener); 从您的专用构造函数中提取出来。这不是其他答案中可变参数技巧的替代方法。您可以应用这两种技巧来获得更小的代码。

public class ShortcutButton extends JButton {
    /** Construct a ShortcutButton without keystrokes. Any constructor calling this should add keystrokes themselves. */
    private ShortcutButton(String text, ActionListener actionListener) {
        super(text);
        addActionListener(actionListener);
    }

    public ShortcutButton(String text, KeyStroke[] keyStrokes, ActionListener actionListener) {
        this(text, actionListener);
        addShortcut(keyStrokes);
    }

    public ShortcutButton(String text, KeyStroke keyStrokes, ActionListener actionListener) {
        this(text, actionListener);
        addShortcut(keyStrokes);
    }

    public ShortcutButton(String text, String[] keyStrokes, ActionListener actionListener) {
        this(text, actionListener);
        addShortcut(keyStrokes);
    }

    public ShortcutButton(String text, String keyStrokes, ActionListener actionListener) {
        this(text, actionListener);
        addShortcut(keyStrokes);
    }
    ...
}

【讨论】:

    【解决方案3】:

    您可以创建如下所示的泛型方法:

     public<T> void addShortcuts(T[] keyStrokes) {
         for (T keyStroke : keyStrokes) {
             addShortcut(keyStroke);
         }
     }
    

    【讨论】:

    • new ShortcutButton(text, 123, actionListener) -> 失败
    • @MarkJeronimus 感谢您指出这一点。我将构造函数误认为方法。提问者可以使用其他答案中提到的方法。并且上述方法可以用于 addShortcut 方法。
    猜你喜欢
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多