Why data Shadowing with instance variables is not working in my program?

99封情书 提交于 2019-12-08 12:15:31

问题


I have three classes which are shown below ,for a game GUI:-

//this is the parent class.
import javax.swing.*;
import java.awt.*;
public class GameGui extends JFrame{
      public void decorateButton(JButton aBut,Color forg,Color back){
         Font afont = new Font(Font.SANS_SERIF,Font.PLAIN,18);
         aBut.setFont(afont);
         aBut.setBackground(back);
         aBut.setForeground(forg);
      }
      public void setFrameDefault(){
         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         this.setSize(400, 475);
         this.setLocationRelativeTo(null);
         this.setResizable(false);
     }
     public void setConstraints(int x,int y,int weightx,int weighty,GridBagConstraints gbc){
         gbc.weighty=weighty;
         gbc.weightx=weightx;
         gbc.gridx=x;
         gbc.gridy=y;
     }
}

//this class is for result to be shown for the game.

import javax.swing.*;
import java.awt.*;
class Result extends GameGui{
      JPanel mainPanel = new JPanel();
      JLabel backImage = new JLabel();//I want this variable to be shadowed by the subclass variable,but it is not happening. 
      JButton continueGame = new JButton("continueGame");
      JButton exitGame = new JButton("exitGame");
      public Result(){
            this.setFrameDefault();
            backImage.setLayout(new BorderLayout());
            this.setContentPane(backImage);
            mainPanel.setLayout(new GridBagLayout());
            decorateButton(continueGame,Color.green,Color.white);
            decorateButton(exitGame,Color.green,Color.white);
            setGui();
      }
      public void setGui(){
            GridBagConstraints gbc = new GridBagConstraints();
            mainPanel.setOpaque(false);
            gbc.gridy=200;
            gbc.gridx=0;
            gbc.insets=new Insets(410,0,0,130);
            mainPanel.add(continueGame,gbc);
            gbc.gridx=GridBagConstraints.RELATIVE;
            gbc.insets = new Insets(410,0,0,0);
            mainPanel.add(exitGame,gbc);
            setFrameDefault();
            this.getContentPane().add(mainPanel);
      }

 }

 //this class is for showing the result for a Win.

 import javax.swing.*;
 import java.awt.*;
 public class Win extends Result{
        JLabel backImage = new JLabel(new ImageIcon("C:\\Users\\BSK\\Desktop\\win.png"));//Problem is here as i have declared the same named JLabel as in Result class but iam not getting the image as background.
        public static void main(String[] args) { //this main method is for testing.
            Win w = new Win();
            w.setVisible(true);
        }
 }

I need two classes at end of hierarchy which are Win and Defeat(second one i have not implemented).I need this because i want wining frame and Defeat frame only differ in the image.
So my question is that although i have declared same named JLabel as backImage in both the classes Result and Win,why i am not getting the image at background?I have tested it by putting the image in JLabel backImage of Result class and then it works!But i want to take the advantage of data shadowing because in my Defeat class(which also extends Result)i will name JLabel having same name as backImage but with different image set to it.I hope you understand,So what is the way out?
Thanks in advance.

NOTE please test with your image.


回答1:


Shadowing affects which variable a name refers to. That is, since the subclass Win defines its own backImage instance variable, methods of Win that refer to backImage will refer to the instance variable in Win (and thus its value) rather than the one in the superclass, Result.

Shadowing does not replace an object that variables and other objects point to. That is, the superclass Result still defines its own backImage instance variable, and Result's methods still refer to that variable (and thus its value). So Win#backImage shadows Result#backImage but it doesn't change how Result works.

Also note that the initialization lines like JLabel backImage = ... run as part of a class's constructor, and the subclass Win's constructor begins by running its superclass Result constructor. So if the subclass didn't declare another backImage and its constructor assigned a new value to the inherited instance variable Result#backImage, this would happen after the Result constructor built the content pane, so it wouldn't change the display.

You could change the contents of the backImage object:

public class Win extends Result {
  public Win() {
    super();
    backImage.setIcon(new ImageIcon("C:\\Users\\BSK\\Desktop\\win.png"));
  }

  ...

to modify backImage's icon for the Win subclass.




回答2:


Fields in Java don't get overriden as methods, so this will not work for you. Fortunately, there are plenty solutions.

One of them (i'm definetly not saying the best one!) is to make your Result game abstract with abstract getIcon() method or something and call that from your setGui() method, then your Win/Lose classes will just return different icons in there.



来源:https://stackoverflow.com/questions/24599565/why-data-shadowing-with-instance-variables-is-not-working-in-my-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!