我可以在另一个类中使用一个类(构造函数+方法)中的代码吗? (JAVA)

时间:2015-05-08 22:59:01

标签: java swing inheritance redundancy

我正在制作一款游戏,而我正试图摆脱代码中的所有冗余。我的所有面板(PlayPanelHighScoreQuit,..)都有很多共同属性,因此我在所有面板中都进行了IPanel类扩展。它看起来像这样:

package menu;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class IPanel extends JPanel implements ActionListener{

    public Image achtergrond;
    public Tanks mainVenster;

    public String backgroundPath; 



    public IPanel(String backgroundPath, Tanks mainVenster)
    {    
        super();
        this.mainVenster = mainVenster;
        this.setLayout(null);

        this.backgroundPath = backgroundPath;
        achtergrond = new     //achtergrond is dutch for background
            ImageIcon(getClass().getResource(backgroundPath)).getImage();

    }

    public void paintComponent(Graphics g)
    {
            super.paintComponent(g);
            g.drawImage(achtergrond, 0, 0, this.getWidth(), this.getHeight(), 
                this);
    }


    public void actionPerformed(ActionEvent ae) 
    {
        mainVenster.switchPanel();
    }

    public void switchPanel(Tanks toActivate)
    {
        remove(mainVenster);
        mainVenster = toActivate;
        add(mainVenster);   //this is wrong, no idea what to do actually

        validate();
        repaint(); 
    }

    }

我可以在其他类中使用构造函数,但我不知道如何使用 其他类中的paintComponentactionPerformed 方法。我在所有面板中使用这两种方法,所以我认为没有必要为所有这些面板重新编写方法。

我的某个面板的示例是QuitPanel

package menu;

 import java.awt.Color;
 import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.Image;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;

 import javax.swing.*;



@SuppressWarnings("serial")
 public class QuitPanel extends JPanel implements ActionListener 
{

     public Button yesKnop, noKnop;
     public JLabel label;
     public Tanks mainVenster;
     public QuitPanel quitPanel;

     public IPanel quit;


    public QuitPanel(Tanks mainVenster)
    {

         quit = new IPanel("/achtergronden/menu.jpg", mainVenster);

         int x = 95, width = 200, height = 50;

         label = new JLabel("ARE YOU SURE?");
         Font font = new Font("Courier", Font.BOLD, 25);
         label.setFont(font);
         label.setBounds(x+20, 400, width, height);

         yesKnop = new Button("/buttons/YES.png",x, 450, this);     
         noKnop = new Button("/buttons/NO.png",x, 525, this);

         this.add(quit);
         this.add(label);
         this.add(noKnop);
         this.add(yesKnop);

    }


     public void actionPerformed(ActionEvent ae) 
    {
        if(ae.getSource() == noKnop)
            quit.switchPanel(mainVenster); //this is wrong
        else if(ae.getSource() == yesKnop)
            System.exit(0); 

    }

}

正如您所看到的,我使用JPanel扩展了课程,因为当我尝试扩展IPanel时,我在public HTPPanel(Tanks mainVenster)处遇到错误 the error

当我打开我的quitPanel时,我得到了这个: quitPanel when opened

所以我知道必须有一部分代码正确,唯一的问题是我的后台无法加载 - > (public void paintComponent(Graphics g)方法)

问题是:我如何使用我在类nr 2中的类nr 1中创建的方法?

另外, noButton 无效(yesButton工作正常) - > (public void actionPerformed(ActionEvent ae)方法) - >也是因为public void switchPanel(Tanks toActivate)我猜

非常感谢你!

4 个答案:

答案 0 :(得分:3)

是的,你可以,并且有两种普遍的方法,构成和相互作用。

使用组合,您可以通过创建并保存代码保存类的实例,将代码推送到当前解决方案所使用的新类中。

使用继承,您可以创建当前解决方案扩展的类,并将代码放在该父类的方法中。然后你有“其他”类扩展包含所需代码的类。

通常,组合比继承更容易处理;但是,随着时间的推移,你会发现继承是更好的解决方案,因为它能够利用多态性。

答案 1 :(得分:1)

错误是因为当你扩展IPanel时,你应该使用至少一个super的构造函数。在这种情况下,有一个,所以你必须使用:

public IPanel(String backgroundPath, Tanks mainVenster)

CORRECTION

不一定你需要(对我来说似乎很理想),但在构造函数中,需要使用{{1}调用superclass's构造函数之一}。

意思是,如果我的课程super(...)有构造函数:

A

和班级public class A { public A(String name) { } } ,我可以做一些事情:

B extends A

无论如何,最后,如果您的public class B { // Option 1: Superclass's Constructor public B(String name) { super(name); } // Option 2: Pass static value public B() { super("something here"); } // Option 3: Use null public B() { super(null); } } 仅包含superclass constructors,则每个parameters子类都需要调用constructor到其中一个super(...)

如果您在superclass's constructors中添加了默认constructor例如:public A() {},则无需在其中任何一个上调用superclass

答案 2 :(得分:0)

你应该将没有参数的默认构造函数添加到IPanel类中, e.g。

public IPanel() { }

然后您可以使用父类IPanel进行扩展。

答案 3 :(得分:0)

如果指定构造函数,编译器不会为您创建没有参数的构造函数(您在IPanel类中执行了此操作)。

public class A {
    public A(String str) { 
        //Compiler will not create a constructor without parameters.
    }
}

反过来,如果你没有指定构造函数,编译器将为你创建一个没有参数的构造函数(你在HTPPanel类中这样做了。)

public class A {
    //Compiler will create a constructor without parameters.
}

现在的问题是,在扩展其他类的类中,默认构造函数将调用它的超类构造函数而不带参数。

public class A {
    public A(String str) {}
}

public class B extends A {}

public class C {
    public static void main(String[] args) {
        B b = new B(); //Compile error
    }
}

但是如果你在类B中指定构造函数,但是没有添加对它的超类构造函数的调用,编译器将自动调用超类构造函数而不带参数

public class A {
    public A(String str) {}
}

public class B extends A {
    public B(int i) {}
}

public class C {
    public static void main(String[] args) {
        B b = new B(); //Compile error
    }
}

换句话说,你应该在你的IPanel类中添加一个没有参数的构造函数,(或者用适当的参数添加对超级构造函数的调用),但我相信这不是你想要做的。

现在,至于你的其他问题,可能是由于多种原因,如果没有完整的代码,它总是一个猜测。还要考虑一下,当您要使用某个Panel类扩展IPanel类时,如果您想要覆盖此面板中的paintComponent方法并仍然绘制背景,则应调用super.paintComponent(g);,试着找出为什么