java - (Java) 使用子类时代码可以工作,但使用父类(super class)会导致空指针错误?

标签 java nullpointerexception

我正在编写一个玩黑桃的程序。

我有一个类,GenericSpadesPlayer

和两个子类

SpadesPlayer 扩展了 GenericSpadesPlayer(这些是计算机播放器。),并且 HumanSpadesPlayer 扩展了 GenericSpadesPlayer

GenericSpadesPlayerClass 的整体结构如下:

import java.io.*;
import java.util.*;

    public abstract class GenericSpadesPlayer{

      Set<Card> hand;
      int playerKey;

  public abstract Card playCard(Card[] playedCards, int[] bids, int[] tricksTaken, int leadSuit);
  public abstract int getBid();

}

每个成员变量和方法都在 SpadesPlayer 和 HumanSpadesPlayer 类中实现,并且这两个类编译时都没有错误。

问题出在运行游戏的类的 main 方法中。最初,我只创建了 SpadesPlayer 对象,我的代码如下:

SpadesPlayer north = new SpadesPlayer(3);
SpadesPlayer south = new SpadesPlayer(1);
SpadesPlayer east = new SpadesPlayer(4);
SpadesPlayer west = new SpadesPlayer(2);

SpadesPlayer[] rotation = {south, west, north, east};

然后,当我发牌时:

for (int i=0; i<deck.deck.length; i++){
  rotation[currentPos].hand.add(deck.dealCard()); //currentPos is initialized to be 1
  currentPos = (currentPos + 1) % 4;
}

一切正常。

当我开发 GenericSpadesPlayer 类并允许 SpadesPlayer 和 HumanSpadesPlayer 继承它时,问题就出现了。当我改变时:

SpadesPlayer[] rotation = {south, west, north, east};

GenericSpadesPlayer[] rotation = {south, west, north, east};

,我在以下行中遇到错误:

rotation[currentPos].hand.add(deck.dealCard());

尝试调试后,程序显示rotation[currentPos].hand 为空。 Hand 在 GenericSpadesPlayer 中没有初始化,因为它是一个抽象类;然而,south、west、north 和 east(旋转数组的所有元素)都是 SpadesPlayers 或 HumanSpadesPlayers,并且 hand 在它们的构造函数中初始化。还应该注意的是,无论我在旋转数组中包含 SpadesPlayers 或 HumanSpadesPlayers 的哪种组合,只要将旋转声明为 GenericSpadesPlayers 而不是 SpadesPlayers 的数组,我总是会收到此错误。

有什么建议吗?我认为制作一个 GenericSpadesPlayers 数组可以让我用 SpadesPlayers 和 HumanSpadesPlayers 填充它,但我似乎遇到了问题。

最佳答案

Each of these member variables and methods are implemented in the SpadesPlayer and HumanSpadesPlayer classes, and both classes compile without errors.

我怀疑这就是问题所在。如果您重新声明Set<Card> hand在您的子类中,它将覆盖 Set<Card> hand在你的父类(super class)中。然后,一旦将数组从子类切换到父类(super class),您将得到一个空点异常。

您不需要重新声明Set<Card> hand在您的子类中,您已经可以自由访问它们。当您从类继承时,您可以访问它的所有变量和方法。您只是无法在子类代码中真正看到它们。

这是一个简单的示例。

super 类 List ,未初始化。如果我尝试使用这个变量,我将得到一个空指针异常。

public class mySuper {

    public static List<Integer> test;

}

继承自上述类的子类。我重新声明了变量,我认为这就是你所做的。我还初始化了它,所以如果我尝试使用这个变量,我将不会得到空指针异常。

public class mySub extends mySuper{

    public static List<Integer> test = new ArrayList<Integer>();

}

主要方法,与您的类似。

public static void main(String[] args){
        mySub[] mySubArray = {new mySub()};
        System.out.println(mySubArray[0].test.size()); //prints 0

        mySuper[] mySuperArray = {new mySub()}; 
        System.out.println(mySuperArray[0].test.size()); //null pointer exception
    }
<小时/>

如何解决这个问题。

正确初始化父类(super class)中的变量。

public class mySuper {

    public static List<Integer> test  = new ArrayList<Integer>();

}

把子类中的声明去掉,仍然可以使用。

public class mySub extends mySuper{


}

public static void main(String[] args){
        mySub[] mySubArray = {new mySub()};
        System.out.println(mySubArray[0].test.size()); //prints 0

        mySuper[] mySuperArray = {new mySub()}; 
        System.out.println(mySuperArray [0].test.size()); //prints 0
    }

您可以重新分配子类中的变量。但是,如果您重新声明它,那么它就会覆盖父类(super class)变量。

关于java - (Java) 使用子类时代码可以工作,但使用父类(super class)会导致空指针错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33313083/

相关文章:

java - A 星、H 值空指针 (Java)

java - 获取已安装在 OSGi 运行时中的 bundle 的 InputStream?

java - Tomcat 7 无法加载 javax.persistence

java - 将 jsp 文件合并/叠加到特定位置

java - 为什么我在这里得到 NullPointerException?

Android - fragment 中的 SensorEventListener

java - 为什么我得到这个 NullPointerException?

java - 如何调试: Exception in thread "AWT-EventQueue-0" java. lang.NullPointerException

java - SocketTimeoutException 指示无法访问

java - Android动态添加自定义组件到LinearLayout