如何在Java中实现多个类的代码?

时间:2012-06-30 04:29:53

标签: java class inheritance

我有两个类:JDialog和JFrame(见下文)。现在我希望它们获得一些额外的功能,但是我希望这两个类都扩展我的代码,而不需要编写两次代码。有没有办法做到这一点?

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(),将窗口移动到屏幕上的用户友好位置 - 我知道,这只是一个例子。我希望该方法适用于JDialogJFrame。使用继承,我必须编写两个类,例如MagicJDialogMagicJFrame,每个类以完全相同的方式实现方法moveWindowToMagicPositionOnScreen()。嗯,这很多余。所以我不想让代码写两次。在某种程度上,我希望一个类使用另一个类的代码。

4 个答案:

答案 0 :(得分:1)

不幸的是,Java不支持mixins。在这里采用最简单,最清晰的方法是使用组合,在这种情况下,您只需要编写两次包装器,但实际的实现只存在于一个位置。

答案 1 :(得分:1)

像其他几个人所建议的那样,更喜欢构图而不是继承。但是,您可以为方法创建公共接口:

public interface Magic {
    void moveWindowToMagicPositionOnScreen();
}

如果移动窗口的代码完全,则创建一个委托类:

public class MagicDelegate implements Magic {

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

然后让您的两个类使用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()方法。

答案 2 :(得分:1)

界面/代表/构图想法可能是“最干净”的。但是,一个可接受且可以说更简单的替代方法是使用静态方法创建实用程序类。

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

在实践中,我可能会将计算逻辑放入另一种方法computeMagicPositionOnScreen()中。如果它有意义(可能没有),这个静态实用程序类实际上可能是一个“真正的”(非静态)类,比如MagicPositionCalculator,可能有多个实例,比如说每个屏幕一个,一个用于真正的大屏幕,一个用于高级用户等......

答案 3 :(得分:0)

试试这个,

我认为你想要应用 DRY (Don't Repeat Yourself)设计原则和部分 LSP (Liskov substitution Principle),如果你想要一些方法存储在一个class,然后从其他两个类使用此方法,然后我认为更喜欢编写而不是继承将是一个好主意。因为您可以使用所需的方法而无需继承您不需要的方法。