变量(可能)超出范围

时间:2015-10-12 13:09:34

标签: java inheritance scope

好的,有两个类Player和子类Classes。我使用子类通过switch语句在主类中设置玩家统计数据,让用户选择他的类。但由于某种原因,在主类中执行时,set变量超出了范围。为了爱我,我无法理解为什么会发生这种情况

以下是Player类:

public class Player {
private int HP;
private int ATK;
private int DEF;
private int DAMAGE;

    void setHP(int a){
    HP=a;
    }

    void setATK(int a){
    ATK=a;
    }

    void setDEF(int a){
    DEF=a;
    }

    void setDAMAGE(){
    DAMAGE = damageCalculation();
    }

    int damageCalculation(){
    int damage = (2*ATK);    
    return damage;
    }

Player(String Class){
    Classes classes = new Classes();
switch(Class){
    case "Barbarian":
        classes.Barbar();
        System.out.println("Done");
        break;
        case "Rogue":
        break;
    default: System.out.println("Error");
}
}

void getStats(){
System.out.format("Player stats:"
        + "\nHP: %d"
        + "\nATK: %d"
        + "\nDEF: %d"
        + "\nDAMAGE: %d\n",HP,ATK,DEF,DAMAGE);
}
}

这是Classes类(请注意,在子类get stats中返回有效值):

public class Classes extends Player {

public void Barbar(){
Player player = new Player();   
player.setHP(60);
player.setATK(15);
player.setDEF(25);
player.setDAMAGE();
player.getStats();
 }
} 

这是main类:

import java.util.Scanner;
public class SurvivalGame {

   public static void main(String[] args) {
    Scanner scan = new Scanner(System.in,"Windows-1250");
    System.out.println("Enter your class");
    Player player = new Player(scan.nextLine());
    player.getStats(); //here getStats return zeros,
    //possibly out of scope variables if player enters Barbarian
 }
}

3 个答案:

答案 0 :(得分:1)

public void Barbar(){
Player player = new Player();   

如果你仔细观察,你会创建一个新的播放器并为其添加值,而不是主方法中的播放器。

答案 1 :(得分:0)

当你扩展一个类时,你会获得一些超类的实例,但是你选择在子类中添加额外的方法和字段。所以当你写

public class Classes extends Player {
    //...
}

您的Classes个实例中已包含HP个(等)字段。您的Barbar方法可以修改它们,而无需创建Player的新实例:

public void Barbar(){
    setHP(60);
    setATK(15);
    setDEF(25);
    setDAMAGE();
    getStats();
}

您感到困惑撰写继承

答案 2 :(得分:0)

您正在创建一个永远不会被访问的Player的额外实例。只需浏览您的代码:

/* Main Method */
// You get a new Player object using direct user input
// (Which is somewhat dangerous, you should do some data validation first)
Player player = new Player(scan.nextLine())

/* Player constructor */
// Let's say user entered correctly "Barbarian". You are in the process of constructing
// a new Player object when you call this:
classes.Barbar();

/* Barbar method */
// The very first line creates a brand new player - different from one you were
// in the process of constructing. 
Player player = new Player(); 
// Then you assign values to the new Player, which goes out of scope as soon as the
// method ends. 

而不是让Classes扩展Player(这对我来说似乎有点奇怪,说实话),我只是让Barbar方法属于Player类本身(可以然后在你的switch语句中调用)。然后,您可以直接修改当前播放器的值,而不是依赖于不同的类来为您执行此操作。

例如:

public class Player 
{
    public Player(String class)
    {
        switch (class)
        {
            case "Barbarian": 
                Barbar();
                break;
        }
    }

    public void Barbar()
    {
        HP = 60;
        ATK = 15;
        DEF = 25;
        setDAMAGE();
    }
}