【问题标题】:can i use the code from one class (constructor + methods) in another class? (java)我可以在另一个类中使用一个类(构造函数+方法)的代码吗? (爪哇)
【发布时间】:2015-05-08 22:59:00
【问题描述】:

我正在制作一款游戏,并试图消除代码中的所有冗余。我所有的面板(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) 出现错误,上面说

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

所以我知道我的代码中一定有一部分是正确的,唯一的问题是我的 背景没有加载 --> (public void paintComponent(Graphics g) 方法)

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

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

非常感谢!

【问题讨论】:

    标签: java swing inheritance redundancy


    【解决方案1】:

    是的,你可以,并且有两种通用方法,组合和交互。

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

    通过继承,您可以创建一个当前解决方案扩展的类,并将代码放入该父类的方法中。然后你让“其他”类扩展包含所需代码的类。

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

    【讨论】:

      【解决方案2】:

      错误是因为当您扩展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 仅包含constructorsparameters,则子类的每个constructor 都需要将super(...) 调用到superclass's constructors 之一。

      如果您在superclass 中设置了默认的constructor,例如:public A() {},则您无需在其中任何一个上调用super()

      【讨论】:

        【解决方案3】:

        您应该将不带参数的默认构造函数添加到 IPanel 类, 例如

        public IPanel() { }
        

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

        【讨论】:

        • 这似乎是一个合理的答案,但我真的不明白如何在没有我想要的参数的情况下调用构造函数......
        【解决方案4】:

        如果您指定构造函数,编译器不会为您创建没有参数的构造函数(您在 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);,试着弄清楚为什么

        【讨论】:

          猜你喜欢
          • 2015-07-17
          • 2010-11-02
          • 2017-05-03
          • 1970-01-01
          • 2020-11-07
          • 2012-11-26
          • 1970-01-01
          • 2019-04-17
          • 1970-01-01
          相关资源
          最近更新 更多