我可以在另一个类中使用一个类(构造函数+方法)的代码吗? (java)
我正在做一个游戏,我正在尝试去掉代码中的所有冗余。我所有的面板(PlayPanel
,HighScore
,Quit
,..)都有很多共同的特性,所以我在所有面板中都制作了IPanel
类。它看起来像这样:我可以在另一个类中使用一个类(构造函数+方法)的代码吗? (java)
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)
我猜
太感谢你了!
是的,你可以,有两种广义的方法,组成和interhitence。
通过组合,您可以将代码推入您的当前解决方案然后使用的新类,方法是创建并保存代码保存类的实例。
通过继承,您可以创建一个当前解决方案扩展的类,并将代码放入该父类的方法中。然后你有“其他”类扩展包含所需代码的类。
一般来说,构成比继承更容易处理;但随着时间的推移,由于能够利用多态性,您将会意识到何时继承是更好的解决方案。
您应该将不带参数的默认构造函数添加到IPanel类,例如
public IPanel() { }
然后你可以使用你的父类IPanel进行扩展。
错误是因为在扩展IPanel
时,您至少需要使用super
的构造函数中的一个。在这种情况下,有一个,所以你不得不使用:
public IPanel(String backgroundPath, Tanks mainVenster)
修正
它不一定是你需要到(似乎理想对我来说),但在一个构造函数,其中一个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
之一。
如果您在您的superclass
中放置了默认的constructor
例如:public A() {}
,那么您不需要在其中任何一个上调用super()
。
如果指定一个构造函数,编译器不会为您创建没有参数的构造函数(您在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
}
}
换句话说,您应该添加一个构造函数与您茁壮类没有参数,(或加用适当的参数超级构造函数的调用),但我相信这不是你想在这里做什么。
现在,至于你的其他问题,这可能是由于多种原因,它将永远是没有完整代码的猜测。另外考虑一下,当你打算用一些Panel类扩展IPanel类时,如果你想重写这个面板中的paintComponent
方法并且仍然绘制背景,你应该调用super.paintComponent(g);
,试图找出为什么。
这似乎是一个合理的答案,但我真的不明白如何我可以调用构造函数没有我想要的参数... – Lola