简体   繁体   English

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

[英]can i use the code from one class (constructor + methods) in another class? (java)

I'm making a game and I'm trying to ged rid of all the redundancy in my code. 我正在制作游戏,并且试图消除代码中的所有冗余。 All my panels( PlayPanel , HighScore , Quit ,..) have a lot of properties in common so i made a class IPanel to extend in all my panels. 我所有的面板( PlayPanelHighScoreQuit等)都有很多共同的属性,因此我制作了一个IPanel类以扩展到我的所有面板中。 it looks like this: 它看起来像这样:

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(); 
    }

    }

I'm able to use the constructor in other classes, but i don't know how to use the paintComponent and actionPerformed methods in other classes . 我可以在其他类中使用构造函数,但是我不知道如何在其他类中使用paintComponentactionPerformed 方法 I use these 2 methods in all of my Panels so i think it's unnecessary to write the methods all over again for all these panels. 我在所有面板中都使用了这两种方法,因此我认为没有必要为所有这些面板重新编写方法。

an example of one of my panels is QuitPanel : 我的面板之一的示例是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); 

    }

}

as you can see i extended the class with JPanel because when i tried to extend IPanel i got an error at public HTPPanel(Tanks mainVenster) that said 如您所见,我使用JPanel扩展了该类,因为当我尝试扩展IPanelpublic HTPPanel(Tanks mainVenster)上出现了错误, 错误

when i open my quitPanel i get this: 当我打开quitPanel时,我得到以下信息: 打开时退出面板

so i know there must be a part of my code correct, the only problem is the fact that my background doesn't load --> ( public void paintComponent(Graphics g) method) 所以我知道代码的一部分必须正确,唯一的问题是我的背景无法加载 ->( public void paintComponent(Graphics g)方法)

the question is: how do i use the method i created in class nr 1 in class nr 2? 问题是:如何使用在nr 2类中在nr 1类中创建的方法?

also, the noButton isn't working (yesButton is working fine) --> ( public void actionPerformed(ActionEvent ae) method in ) --> also because of public void switchPanel(Tanks toActivate) i guess 另外, noButton不能正常工作(yesButton可以正常工作)->( public void actionPerformed(ActionEvent ae)方法)->也因为public void switchPanel(Tanks toActivate)

thank you so much! 非常感谢!

Yes you can, and there are two generalized approaches, composition and interhitence. 是的,您可以,并且有两种通用的方法,即合成和相互影响。

With composition, you push the code into a new class that your current solution then uses by creating and holding an instance of the code-holding class. 通过组合,您可以通过创建并保存代码保存类的实例,将代码推送到当前解决方案然后使用的新类中。

With inheritance, you create a class that your current solution extends, and put the code in a method in that parent class. 通过继承,您可以创建当前解决方案扩展的类,并将代码放入该父类的方法中。 Then you have the "other" class extend the one that contains the desired code. 然后,您可以在“其他”类中扩展包含所需代码的类。

Generally, composition is easier to handle over time than inheritance; 通常,随着时间的推移,合成比继承要容易处理。 but, with time, you will recognize when inheritance is the better solution due to it's ability to leverage polymorphisim. 但是随着时间的流逝,您将认识到继承是更好的解决方案,因为继承可以利用多态性。

The error is because when you're extending IPanel , you're expected to use at least one of the super 's constructors. 该错误是因为在扩展IPanel ,应该至少使用super的构造函数之一。 In this case, there's one, so you'd have to use: 在这种情况下,只有一个,因此您必须使用:

public IPanel(String backgroundPath, Tanks mainVenster)

CORRECTION 更正

It isn't necessarily that you need to (it seems ideal to me), but in a constructor, one of the superclass's constructors need to be called with super(...) . 不一定需要 (这对我来说似乎很理想),但是在构造函数中,需要使用super(...)调用superclass's构造函数之一。

Meaning, if I had class A with its constructor: 意思是,如果我有A类及其构造函数:

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

and class B extends A , I could do a few things: B extends AB 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);
    }
}

No matter what, in the end, if your superclass only contains constructors with parameters , every constructor of the subclass will need to call super(...) to one of the superclass's constructors . 不管如何,在最后,如果你的superclass仅包含constructorsparameters ,每一个constructor的子类需要调用super(...)到一个superclass's constructors

If you put a default constructor eg: public A() {} in your superclass , you won't need to call super() on any of them. 如果您将默认constructor例如: public A() {}放在您的superclass ,则无需在任何一个上调用super()

you should add the default constructor without parameters to the IPanel class, eg 您应该将不带参数的默认构造函数添加到IPanel类,例如

public IPanel() { }

then you can use your parent class IPanel for extending. 那么您可以使用父类IPanel进行扩展。

If you specify a constructor, the compiler is not going to create a constructor without parameters for you (you did this in your IPanel class). 如果指定构造函数,则编译器将不会为您创建不带参数的构造函数(您在IPanel类中做到了)。

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

Reversed, if you don't specify a constructor, the compiler is going to create a constructor without parameters for you (you did this in your HTPPanel class). 相反,如果不指定构造函数,则编译器将为您创建不带参数的构造函数(您在HTPPanel类中完成了此操作)。

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

Now the thing is that in a class that extends some other class, the default constructor will call it's superclass constructor with no arguments. 现在的事情是,在扩展其他类的类中,默认构造函数将调用其无参数的超类构造函数。

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
    }
}

But also if you specify the constructor in class B, but do not add a call to it's superclass constructor, the compiler will automatically call the superclass constructor without arguments . 而且,如果您在类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
    }
}

In other words, you should either add a constructor with no parameters in your IPanel class, (or add a call to the super constructor with appropriate arguments), but I believe that's not what you want to do here. 换句话说,您应该在IPanel类中添加不带任何参数的构造函数(或添加具有适当参数的对超级构造函数的调用),但是我相信这不是您想要在此处执行的操作。

Now, as for your other questions, it can be due to multiple reasons and it will always be a guess without full code. 现在,关于您的其他问题,可能是由于多种原因造成的,并且如果没有完整的代码,将永远是一个猜测。 Also consider, that when you're going to extend the IPanel class with some Panel class, that if you want to override the paintComponent method in this panel and still draw the background, you should call super.paintComponent(g); 还要考虑一下,当要使用某些Panel类扩展IPanel类时,如果要覆盖此面板中的paintComponent方法并仍然绘制背景,则应调用super.paintComponent(g); , try to figure out why . ,尝试找出原因

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM