[英]can i use the code from one class (constructor + methods) in another class? (java)
我正在制作游戏,并且试图消除代码中的所有冗余。 我所有的面板( PlayPanel
, HighScore
, Quit
等)都有很多共同的属性,因此我制作了一个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();
}
}
我可以在其他类中使用构造函数,但是我不知道如何在其他类中使用paintComponent
和actionPerformed
方法 。 我在所有面板中都使用了这两种方法,因此我认为没有必要为所有这些面板重新编写方法。
我的面板之一的示例是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)
上出现了错误,
当我打开quitPanel时,我得到以下信息:
所以我知道代码的一部分必须正确,唯一的问题是我的背景无法加载 ->( public void paintComponent(Graphics g)
方法)
问题是:如何使用在nr 2类中在nr 1类中创建的方法?
另外, noButton不能正常工作(yesButton可以正常工作)->( public void actionPerformed(ActionEvent ae)
方法)->也因为public void switchPanel(Tanks toActivate)
非常感谢!
是的,您可以,并且有两种通用的方法,即合成和相互影响。
通过组合,您可以通过创建并保存代码保存类的实例,将代码推送到当前解决方案然后使用的新类中。
通过继承,您可以创建当前解决方案扩展的类,并将代码放入该父类的方法中。 然后,您可以在“其他”类中扩展包含所需代码的类。
通常,随着时间的推移,合成比继承要容易处理。 但是随着时间的流逝,您将认识到继承是更好的解决方案,因为继承可以利用多态性。
该错误是因为在扩展IPanel
,应该至少使用super
的构造函数之一。 在这种情况下,只有一个,因此您必须使用:
public IPanel(String backgroundPath, Tanks mainVenster)
更正
不一定需要 (这对我来说似乎很理想),但是在构造函数中,需要使用super(...)
调用superclass's
构造函数之一。
意思是,如果我有A
类及其构造函数:
public class A {
public A(String name) {
}
}
B extends A
类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
,则无需在任何一个上调用super()
。
您应该将不带参数的默认构造函数添加到IPanel类,例如
public IPanel() { }
那么您可以使用父类IPanel进行扩展。
如果指定构造函数,则编译器将不会为您创建不带参数的构造函数(您在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);
,尝试找出原因 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.