我正在编写一个程序来玩黑桃。
我有一个班级,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类中实现,并且这两个类的编译都没有错误。
问题在于运行游戏的类的主要方法。最初,我只创建了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());
尝试调试后,程序说旋转[currentPos] .hand为空。 GenericSpadesPlayer中没有初始化Hand,因为它是一个抽象类;但是,南,西,北和东(旋转数组的所有元素)都是SpadesPlayers或HumanSpadesPlayers,并且hand在其构造函数中初始化。还应该注意的是,无论我在旋转数组中包含什么样的SpadesPlayers或HumanSpadesPlayers,我总是会遇到这个错误,只要将旋转声明为GenericSpadesPlayers而不是SpadesPlayers的数组。
有什么建议吗?我想制作一系列GenericSpadesPlayers可以让我用SpadesPlayers和HumanSpadesPlayers填充它,但我似乎遇到了问题。
答案 0 :(得分:1)
这些成员变量和方法中的每一个都在SpadesPlayer和HumanSpadesPlayer类中实现,并且这两个类的编译都没有错误。
我怀疑这是问题所在。如果您在子类中重新声明Set<Card> hand
,它将覆盖超类中的Set<Card> hand
。然后,一旦将数组从子类切换到超类,您将获得零点异常。
您不需要在子类中重新声明Set<Card> hand
,您可以自由访问它们。从类继承时,您可以访问其所有变量和方法。你只能在你的子类代码中看到它们。
这是一个简单的例子。
超级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
}
如何解决此问题。
正确初始化超类中的变量。
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
}
您可以重新分配子类中的变量。但是,如果重新声明,那么当它覆盖超类变量时就是这样。