Java toString和继承的问题
我有我有困难找出一个问题,我有一个toString方法。必须更改toString(),以便它打印有关播放机的所有相关信息(以及 项目)。子类应该覆盖超类toString(),但仍然使用toString() 当这减少了代码重复时,从超类实现中删除 我该怎么做呢 球员级别:Java toString和继承的问题,java,inheritance,tostring,Java,Inheritance,Tostring,我有我有困难找出一个问题,我有一个toString方法。必须更改toString(),以便它打印有关播放机的所有相关信息(以及 项目)。子类应该覆盖超类toString(),但仍然使用toString() 当这减少了代码重复时,从超类实现中删除 我该怎么做呢 球员级别: import java.util.HashMap; public class Player extends Character { private String name; private String type; publ
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;
}
import java.util.HashMap;
公共类玩家扩展角色{
私有字符串名称;
私有字符串类型;
公共静态HashMap背包;
私人运输能力;
/**建造师
*创建一个健康值为100的玩家,一个空背包
*最大承载能力100
*
*@param nick玩家姓名
*@param type玩家类型
*@param minDamage玩家最小伤害
*@param maxDamage玩家最大伤害
*/
公共播放器(字符串名称、字符串类型、int minDamage、int maxDamage){
超级(姓名、minDamage、maxDamage);
集合名(名称);
setType(类型);
健康=100;
黄金=100;
背包=新的HashMap();
最大承载能力=100;
setMinDamage(minDamage);
设置最大损坏(最大损坏);
}
/**
*使用背包中的物品
*@param itemName
*@如果使用项目,则返回true,否则返回false
*如果背包里没有这个名字的东西
*/
公共布尔useItem(字符串itemName){
项目=findItem(项目名称);
如果(项!=null){
System.out.println(name++item.getAction()++++item.getName());
返回true;
}否则{
返回false;
}
}
公共布尔项(字符串项toequip){
Item=findItem(itemToEquip);
如果(项!=null){
this.minDamage=this.minDamage+item.getBonus();
返回true;
}否则{
返回false;
}
}
/**
*将物品添加到玩家库存中
*只有在总重量不符合要求的情况下才能购买该商品
*超过玩家的承载能力
*@param项目
*@return true(如果物品已购买)
*/
公共布尔添加项(项){
int totalWeight=totalWeight()+item.getWeight();
if(总重量0和健康状况100){
健康=100;
}否则,如果(temp 0&&health=5,则minDamage设置为5
*@param最小伤害
*/
公共无效设置损坏(内部损坏){
this.minDamage=minDamage>=5?minDamage:5;
}
/**
*受到最大伤害
*@return最大伤害
*/
public int getMaxDamage(){
返回最大损坏;
}
/**
*设置最大伤害,如果maxDamage一般来说,给定两个类,A
和B
,如果类B扩展了A
,那么B拥有A
的所有属性以及它自己的一些属性。因此,当您实现B
的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()
方法,因此调用super.toString()
相当于调用Object.toString()
。因此,您应该首先为字符抽象类实现toString
例如,您可以执行以下操作:
public String toString() {
return "Name: " + name + "\nHealth: " ... all the attributes
}
但是代码中有很多冗余。首先,您的角色
类和玩家
类都有相同的名称
变量,这与继承点背道而驰。事实上,您甚至从未使用玩家
的名称变量
另外,如果所有变量都声明为公共的,那么在Character
中创建getter/setter方法是没有意义的。最好将它们设置为私有并使用getter/setter。您的抽象超类有name
和health
,但没有type
或backpack
。(我刚刚注意到,多亏了user2573153的回答,您的Player
类中也有name
;我想您不希望这样。)
我认为您要做的第一件事是回答这个问题:假设您创建了一个新的子类,并且没有重写toString()
,然后打印出一个对象。您希望看到打印出什么
也许您希望打印出名称和运行状况。因此,您可以在抽象的字符
类中声明这一点(我认为不应该称为字符
,因为java.lang
已经有了字符
):
然后,如果您想在Player
或Monster
中添加toString()
,那么就很容易了:
@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;
}
在您的实际代码中,您希望在字符串中插入超代码<代码> toString()//C>的“<代码>类型< /代码>信息。这会使事情变得更困难。我可以想出两种方法来处理它。一种是使用一些字符串操作方法来搜索<代码> \n <代码>,并插入“类型”。字符串。但我认为最好将字符串拆分为两个方法。您可以将它们放入
Character
类中:
protected String nameString() {
return "Name: " + name;
}
protected String healthString() {
if(isAlive()) {
return "Is alive with health: " + health;
} else {
return "Is dead.";
}
}
现在,您的Character
中的toString()
@Override
public String toString() {
return nameString() + "\n" + healthString();
}
在播放器中
:
@Override
public String toString() {
String string = "Name: " + name + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
return string;
}
@Override
public String toString() {
return nameString() + " Type: " + type + "\n" + healthString();
}
您仍然可以避免重复代码。(您不需要说super.nameString()
,因为您的子类将自动继承它,并且您不打算重写它。)不会自动调用超类方法。当您在Player中重写toString()并调用toString()时在播放器的实例上运行的唯一代码是播放器的toString()
如果您想将角色的toString()包含在玩家的toString()中,您需要在玩家的toString()中调用super.toString()
你的玩家@Override
public String toString() {
return nameString() + " Type: " + type + "\n" + healthString();
}
/**
* @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;