我无法通过toString方法找出问题。必须更改toString(),以便打印有关Player的所有相关信息(以及 项目)。子类应该覆盖超类toString(),但仍然使用toString() 从超类实现中减少代码重复。
我该怎么做?
玩家类:
import java.util.HashMap;
public class Player extends Character {
private String name;
private String type;
public static HashMap<String, Item> backpack;
private int maxCarryingCapacity;
/**Constructor
* Creates a player with health 100, an empty backpack
* and max carrying capacity 100
*
* @param nick the players name
* @param type the players type
* @param minDamage players minimum damage
* @param maxDamage players maximum damage
*/
public Player(String name, String type, int minDamage, int maxDamage) {
super(name, minDamage, maxDamage);
setName(name);
setType(type);
health = 100;
gold = 100;
backpack = new HashMap<String, Item>();
maxCarryingCapacity = 100;
setMinDamage(minDamage);
setMaxDamage(maxDamage);
}
/**
* Use an item in backpack
* @param itemName
* @return true if item is used, and false
* if there's no item by that name in the backpack
*/
public boolean useItem(String itemName) {
Item item = findItem(itemName);
if(item != null) {
System.out.println(name + " " + item.getAction() + " " + item.getName());
return true;
} else {
return false;
}
}
public boolean equipItem(String itemToEquip) {
Item item = findItem(itemToEquip);
if (item != null) {
this.minDamage = this.minDamage + item.getBonus();
return true;
} else {
return false;
}
}
/**
* Adds item to players inventory. An
* item can only be bought if the total weight does not
* exceed the players carrying capacity
* @param item
* @return true if the item is bought
*/
public boolean addItem(Item item) {
int totalWeight = totalWeight() + item.getWeight();
if(totalWeight <= maxCarryingCapacity){
backpack.put(item.getName(), item);
return true;
} else {
return false;
}
}
/**
* Find item in backpack
*
* @param name of item
* @return item, or null if item is not int the backpack
*/
public Item findItem(String itemName) {
return backpack.get(itemName);
}
/**
* Removes item from player's backpack and
* add item value to player's gold
*
* @param name of item to sell
* @return true if successful
*/
public boolean sellItem(String itemToSell) {
Item item = findItem(itemToSell);
if(item != null) {
gold += item.getValue();
backpack.remove(item.getName());
return true;
} else {
return false;
}
}
/**
* @return true if the player is alive
*/
public boolean isAlive() {
if(health > 0 && health <= 100) {
return true;
} else return false;
}
/**
* @return a string with player information
*/
@Override
public String toString() {
String string = "Name: " + name + " Type: " + type + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return string;
}
/**
* @return the players type
*/
public String getType() {
return type;
}
/**Sets the players type
* Valid types: Mage, Ranger, Warrior, Rogue
* @param newType
*/
public void setType(String newType) {
newType = newType.toLowerCase().trim();
if(newType.equals("mage") || newType.equals("ranger") || newType.equals("warrior") || newType.equals("rogue")){
this.type = newType;
} else {
this.type = "Unspecified";
}
}
/**
* @param item
* @return current carrying weight
*/
private int totalWeight() {
int tempWeight = 0;
for(Item itemInBackpack : backpack.values()) {
tempWeight += itemInBackpack.getWeight();
}
return tempWeight;
}
public int attack(Monster currentEnemy) {
int damage = Utils.random(minDamage, maxDamage+1);
currentEnemy.changeHealth(-damage);
return damage;
}
}
Character超类(抽象类):
abstract class Character
{
public String name;
public static int health;
public int gold;
public int minDamage;
public int maxDamage;
public Character(String name, int minDamage, int maxDamage) {
setName(name);
health = 100;
gold = 100;
setMinDamage(minDamage);
setMaxDamage(maxDamage);
}
public Character () {
}
/**
* Changes the character health
* The health can not be less the 0 or "less than or euqal to" 100.
* @param healthPoints
*/
public void changeHealth(int healthPoints) {
int temp = health + healthPoints;
if(temp > 100) {
health = 100;
} else if (temp <= 0) {
health = 0;
} else {
health = temp;
}
}
/**
* @return true if the character is alive
*/
public boolean isDead() {
if(health > 0 && health <= 100) {
return false;
} else return true;
}
/**
* @return the characters name
*/
public String getName() {
return name;
}
/**Set to Unspecified if the string is empty
* @param name
*/
public void setName(String name) {
this.name = Utils.checkString(name);
}
/**
* @return the characters health
*/
public static int getHealth() {
return health;
}
/**
* Get minimum damage
* @return minimum damage
*/
public int getMinDamage() {
return minDamage;
}
/**
* Set minimum damage, if minDamage >= 5, minDamage is otherwise set to 5
* @param minimum Damage
*/
public void setMinDamage(int minDamage) {
this.minDamage = minDamage >= 5 ? minDamage : 5;
}
/**
* Get maximum damage
* @return maximum damage
*/
public int getMaxDamage() {
return maxDamage;
}
/**
* Set maximum damage, if maxDamage <= minDamage, maxDamage is set to minDamage +5
* @param maximum damage
*/
public void setMaxDamage(int maxDamage) {
this.maxDamage = maxDamage <= minDamage ? minDamage+5 : maxDamage;
}
/**
* Get money
* @return amount of money
*/
public int getGold() {
return gold;
}
/**
* Set money
* @param amount of money
*/
public void setGold(int gold) {
this.gold = Utils.checkNegativeInt(gold);
}
}
答案 0 :(得分:3)
一般来说,给定两个类A
和B
以及类B extends A
,那么B具有A
的所有属性以及它自己的一些属性。因此,当您实施B
的{{1}}方法时,您应该这样做:
toString()
但是,您的实施不会为@Override
public String toString() {
String newStuff = // description of the new variables
return super.toString() + newStuff;
// Now describe the elements of B that aren't included in A
}
提供基本toString()
方法,因此调用Character
等同于调用super.toString()
。因此,您应该首先为Object.toString()
抽象类实现toString。
Character
但代码中存在大量冗余。首先,您的public String toString() {
return "Name: " + name + "\nHealth: " ... all the attributes
}
类和Character
类都具有相同的Player
变量,这与继承点相反。实际上,您甚至从未使用name
的名称变量。
另外,如果所有变量都被声明为公共,那么在Player
中创建getter / setter方法是没有意义的。最好将它们设为私有,然后使用getter / setter。
答案 1 :(得分:1)
您的抽象超类有name
和health
,但不是type
或backpack
。 (我刚刚注意到,感谢user2573153的答案,你name
课程中也有Player
;我认为你不想这样做。)
我认为您要做的第一件事就是回答这个问题:假设您创建了一个新的子类,并且不要覆盖toString()
,然后打印出一个对象。你想看到什么打印出来?
也许你想要打印出名字和健康。因此,您可以在抽象的Character
类中声明这一点(我认为不应该将其称为Character
因为java.lang
已经有Character
):
@Override
public String toString() {
String string = "Name: " + name + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
return string;
}
然后,如果您希望toString()
或Player
中的Monster
添加一些内容,那将非常简单:
@Override
public String toString() {
String string = super.toString(); // here's where you call the superclass version
string += "\n Type: " + type;
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return string;
}
但是,在实际代码中,您希望在超类Type
返回的字符串的 middle 中插入toString()
信息。这让事情变得更加艰难。我可以想到两种方法来处理它。一种方法是使用一些字符串操作方法来搜索\n
并插入&#34; Type&#34;在那里的字符串。但我认为将字符串拆分为两种方法会更好。您可以将它们放在Character
课程中:
protected String nameString() {
return "Name: " + name;
}
protected String healthString() {
if(isAlive()) {
return "Is alive with health: " + health;
} else {
return "Is dead.";
}
}
现在,toString()
中的Character
可能看起来像
@Override
public String toString() {
return nameString() + "\n" + healthString();
}
和Player
:
@Override
public String toString() {
return nameString() + " Type: " + type + "\n" + healthString();
}
你仍然可以避免重复的代码。 (你不需要说super.nameString()
,因为你的子类会自动继承它而你不打算覆盖它。)
答案 2 :(得分:0)
不会自动调用超类方法。当您在播放器中覆盖 toString()并在播放器的实例上调用 toString()时,唯一的代码运行的是播放器&#39; toString()。
如果您想在播放器的 toString()中加入字符的 toString(),需要通过在播放器的 toString()中调用 super.toString()来明确说明。
toString()的播放器实施可以修改为包含我的建议如下:
/**
* @return a string with player information
*/
@Override
public String toString() {
String string = "Name: " + name + " Type: " + type + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return super.toString() + string;
}
这一点的显着部分正在发生变化:
return string;
要:
return super.toString() + string;