针对如下文章部分代码进行了修改,使得逻辑上更加通顺,结果符合预期.
原文链接:https://blog.csdn.net/weixin_44170221/article/details/104574963
游戏角色题目
父类:Role(角色),是所有职业的父类
1)属性:name,表示角色的名字
2)方法:public int attack(),该方法返回值为角色的攻击对敌人的伤害
Role的第一个子类:Magicer(法师)
1)属性:魔法等级(范围为1~10)
2)方法:public int attack(),该方法返回法师的攻击对敌人造成的伤害值
法师攻击伤害值为:魔法等级*魔法基本伤害值(固定为5)
Role的第二个子类:Soldier(战士)
1)属性:攻击伤害值
2)方法:public int attack(),该方法返回战士对敌人造成的伤害值
战士的攻击伤害值为:其攻击伤害属性值
再设计一个Team类,表示一个组队。
1)addMember,表示组队增加一个成员
注意:组队成员最多为6人
提示:应当利用一个数组属性,保存所有成员
2)attackSum,表示组队所有成员进行攻击时,对敌人造成的总伤害
在之前的游戏角色Role程序上进行修改
游戏角色(封装、继承、多态版)
创建Role接口,包含两个方法:
1)int attack(); 表示攻击,返回值表示对敌人的伤害
2)void practise(); 表示练习。练习之后对敌人的伤害会增加
创建NamedRole类,该类为一个抽象类,实现了Role 接口,并有两个属性:
1)name:角色的名字
2)age:角色的年龄
增加MagicStick接口。该接口表示法师使用的法杖。接口中包含一个方法:
1)int fire()
为MagicStick类增加两个实现类,分别为GreenStick和BlackStick。其中,对于这两个类的fire方法:
1)GreenStick 平时返回1,夏天(6~8月)使用时返回2
2)BlackStic奇数月返回1,偶数月返回2
修改Magicer类
1)为法师类增加MagicStick类的属性stick,表示法师使用的法杖
2)让其继承自NamedRole类,并实现attack和practise 功能
3)int attack()返回值为法师的魔法等级(level)*每一级的固定伤害(5)
4)void practise()方法:
当法师的stick属性为null时,调用 practise则level++
当法师的stick不为null时,调用practise 方法时,法师的等级level满足:level = level + 1 + stick.fire();即:法师的等级增加为1+stick 属性的fire方法的返回值
增加Weapon接口,表示战士使用的武器。Weapon接口中定义了两个方法:
1)void setSoldier(Soldier s); 该方法表示设置武器的使用者
2)int fire(); 该方法的返回值表示战士使用该武器时,对敌人的伤害值
为 Weapon 增加两个实现了,Bolo,表示大刀,Pike,表示长矛
1)当 soldier 的年龄大于等于 18 岁时,fire 方法返回 100
2)当 soldier 年龄小于 18 岁时,fire 方法返回 50
Pike:Pike 类有一个属性:name,表示长矛的名字
1)当长矛的名字和战士的名字一致时,fire 方法返回 1000
2)当长矛的名字和战士的名字不一致时,fire 方法返回 25
修改 Soldier 类
1)为 Soldier 类增加一个 Weapon 属性,表示战士的武器
2)让其继承自 NamedRole 类,并实现 attack 和 practise 功能。其中
Soldier 的 attack() 返回值为战士的 hurt 值与武器的 fire()返回值的 和,即:总攻击输出 = 战士的徒手伤害值 + 武器的伤害值
practise()方法:每调用一次则战士的 hurt 值+10
编写相应的测试代码
————————————————
整体框架
参考原作者「何学长在奔跑」
API
MagicStick
package cn.zzh.chap8_interface.t17.API;
/**
* @author Zzh
* @desc
* @date 2023/10/10
*/
// 法师使用的法杖
public interface MagicStick {
int fire();
}
Role
package cn.zzh.chap8_interface.t17.API;
/**
* @author Zzh
* @desc
* @date 2023/10/8
*/
public interface Role {
// 表示攻击,返回值表示对敌人的伤害
int attack();
// 表示练习.练习之后对敌人的伤害会增加
void practise();
}
Weapon
package cn.zzh.chap8_interface.t17.API;
import cn.zzh.chap8_interface.t17.Pojo.Soilder.Soldier;
/**
* @author Zzh
* @desc
* @date 2023/10/10
*/
public interface Weapon {
// 表示设置武器的使用者
void setSoldier(Soldier s);
// 返回值表示战士使用该武器时,对敌人的伤害值
int fire();
}
Pojo
Pojo-Magjc
BlackStick
package cn.zzh.chap8_interface.t17.Pojo.Magic;
import cn.zzh.chap8_interface.t17.API.MagicStick;
import java.util.Calendar;
import java.util.Date;
/**
* @author Zzh
* @desc 与原作者的区别在于使用了Calendar进行获取月份
* 且原作者的getMonth方法取得的月份会比实际月份小1,会导致判断错误
* @date 2023/10/10
*/
public class BlackStick implements MagicStick {
// 使用Date获取当前月份(旧)
Date d = new Date();
// 通过Util包的Calendar 获取时间
Calendar cal = Calendar.getInstance();
// 取值为当前月份
// 取值范围是0~11
// cal.get(Calendar.MONTH)
@Override
public int fire() {
if ((cal.get(Calendar.MONTH) +1) % 2 == 0) {
return 2;
} else {
return 1;
}
}
}
GreenStick
package cn.zzh.chap8_interface.t17.Pojo.Magic;
import cn.zzh.chap8_interface.t17.API.MagicStick;
import java.util.Calendar;
/**
* @author Zzh
* @desc
* @date 2023/10/10
*/
public class GreenStick implements MagicStick {
// 通过Util包的Calendar 获取时间
Calendar cal = Calendar.getInstance();
@Override
public int fire() {
// 6~8月返回2,其他返回1
if (cal.get(Calendar.MONTH) + 1 <= 8 && cal.get(Calendar.MONTH) + 1 >= 6)
return 2;
return 1;
}
}
Magicer
package cn.zzh.chap8_interface.t17.Pojo.Magic;
import cn.zzh.chap8_interface.t17.API.MagicStick;
import cn.zzh.chap8_interface.t17.API.Role;
import cn.zzh.chap8_interface.t17.Pojo.NameRole;
/**
* @author Zzh
* @desc
* @date 2023/10/8
*/
public class Magicer extends NameRole implements Role {
// 法师法杖
private MagicStick stick;
private int level;
public Magicer() {
}
public Magicer(String name, int age, int level) {
// 使用public NameRole(String name, int age)构造方法
super(name, age);
setLevel(level);
}
public MagicStick getStick() {
return stick;
}
public void setStick(MagicStick stick) {
this.stick = stick;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
if (level > 10 || level < 1) {
System.out.println("魔法等级范围是1~10,请正确设置技能等级!");
return;
}
this.level = level;
}
@Override
public int attack() {
return 5 * level;
}
/**
* 1.当法师的stick属性为null时,调用practise则level++
* 2.当法师的stick不为null时,调用practise方法时,法师的等级
* level满足:level = level + 1 + stick.fire();
* 即:法师的等级增加为1+stick属性的fire方法的返回值.
*/
@Override
public void practise() {
level++;
if (this.stick != null) {
level += stick.fire();
}
}
}
Pojo-Soldier
Bolo
package cn.zzh.chap8_interface.t17.Pojo.Soilder;
import cn.zzh.chap8_interface.t17.API.Weapon;
/**
* @author Zzh
* @desc
* @date 2023/10/10
*/
public class Bolo implements Weapon {
// 创建属性
private Soldier s;
@Override
public void setSoldier(Soldier s) {
this.s = s;
}
@Override
public int fire() {
if (s == null) {
return 0;
}
// 如果年龄大于18
if (s.getAge() >= 18) {
return 100;
} else {
return 50;
}
}
}
Pike
package cn.zzh.chap8_interface.t17.Pojo.Soilder;
import cn.zzh.chap8_interface.t17.API.Weapon;
/**
* @author Zzh
* @desc
* @date 2023/10/10
*/
public class Pike implements Weapon {
private Soldier s;
// 长矛的名字
private String name;
public Pike(String name) {
this.name = name;
}
@Override
public void setSoldier(Soldier s) {
this.s = s;
}
@Override
public int fire() {
if (s == null) {
return 0;
}
if (s.getName().equals(name)) {
return 1000;
} else {
return 25;
}
}
}
Soldier
package cn.zzh.chap8_interface.t17.Pojo.Soilder;
import cn.zzh.chap8_interface.t17.API.Role;
import cn.zzh.chap8_interface.t17.API.Weapon;
import cn.zzh.chap8_interface.t17.Pojo.NameRole;
/**
* @author Zzh
* @desc
* @date 2023/10/8
*/
public class Soldier extends NameRole implements Role {
private int hurt;
// 战士的武器
private Weapon weapon;
public Soldier() {}
public Soldier(String name) {
super(name);
}
public Soldier(int age) {
super(age);
}
public Soldier(String name, int age, int hurt) {
super(name, age);
setHurt(hurt);
}
public int getHurt() {
return hurt;
}
public void setHurt(int hurt) {
this.hurt = hurt;
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
@Override
public int attack() {
int result = hurt;
if (weapon != null) {
result += weapon.fire();
}
return result;
}
@Override
public void practise() {
this.hurt += 10;
}
}
NameRole
package cn.zzh.chap8_interface.t17.Pojo;
import cn.zzh.chap8_interface.t17.API.Role;
/**
* @author Zzh
* @desc
* @date 2023/10/10
*/
public abstract class NameRole implements Role {
private String name;
private int age;
// 构造方法写全
public NameRole() {
}
public NameRole(String name) {
setName(name);
}
public NameRole(int age) {
setAge(age);
}
public NameRole(String name, int age) {
setName(name);
setAge(age);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int attack() {
return 0;
}
@Override
public void practise() {
}
}
Team
package cn.zzh.chap8_interface.t17;
import cn.zzh.chap8_interface.t17.API.Role;
import cn.zzh.chap8_interface.t17.Pojo.NameRole;
/**
* @author Zzh
* @desc
* @date 2023/10/8
*/
public class Team {
Role[] role;
// 需要传入当前队伍,以及需要加入队伍的角色信息
public void addMember(Role[] role, NameRole memberRole) {
// 如果为false则表示没有加人,否则为加过了
boolean flag = false;
// 遍历队伍,如果有空位就加人,否则不加
for (int i = 0; i < role.length; i++) {
if (role[i] == null) {
role[i] = memberRole;
flag = true;
break;
}
}
if (flag) {
System.out.println(memberRole.getName() + "加入队伍");
} else {
System.out.println("队伍已满");
}
}
public int attackSum(Role[] role) {
int sumDamage = 0;
for (int i = 0; i < role.length; i++) {
sumDamage += role[i].attack();
}
return sumDamage;
}
// 需要传入当前队伍,以及需要加入队伍的角色信息
public void addMember1(NameRole role) {
// 如果为false则表示没有加人,否则为加过了
boolean flag = false;
// 遍历队伍,如果有空位就加人,否则不加
for (int i = 0; i < this.role.length; i++) {
if (this.role[i] == null) {
this.role[i] = role;
flag = true;
break;
}
}
if (flag) {
System.out.println(role.getName() + "加入队伍");
} else {
System.out.println("队伍已满");
}
}
public int attackSum1() {
int sumDamage = 0;
for (int i = 0; i < role.length; i++) {
sumDamage += role[i].attack();
}
return sumDamage;
}
}
Test
(注释代码为修改前题目的测试代码)
package cn.zzh.chap8_interface.t17;
import cn.zzh.chap8_interface.t17.API.Role;
import cn.zzh.chap8_interface.t17.API.Weapon;
import cn.zzh.chap8_interface.t17.API.MagicStick;
import cn.zzh.chap8_interface.t17.Pojo.Magic.GreenStick;
import cn.zzh.chap8_interface.t17.Pojo.Magic.BlackStick;
import cn.zzh.chap8_interface.t17.Pojo.Magic.Magicer;
import cn.zzh.chap8_interface.t17.Pojo.Soilder.Soldier;
import cn.zzh.chap8_interface.t17.Pojo.Soilder.Bolo;
import cn.zzh.chap8_interface.t17.Pojo.Soilder.Pike;
/**
* @author Zzh
* @desc
* @date 2023/10/8
*/
public class Test {
public static void main(String[] args) {
// Magicer m1 = new Magicer();
// Magicer m2 = new Magicer();
// Magicer m3 = new Magicer();
// m1.setLevel(1);
// m2.setLevel(1);
// m3.setLevel(1);
// m1.setName("魔术师1");
// m2.setName("魔术师2");
// m3.setName("魔术师3");
//
// Soldier s1 = new Soldier();
// Soldier s2 = new Soldier();
// Soldier s3 = new Soldier();
// Soldier s4 = new Soldier();
// s1.setHurt(1);
// s2.setHurt(1);
// s3.setHurt(1);
// s4.setHurt(1);
// s1.setName("战士1");
// s2.setName("战士2");
// s3.setName("战士3");
// s4.setName("战士4");
//
// // 创建团队类 参数列表中多个参数用来传递角色数组
// Team team = new Team();
// // 船舰角色数组
// Role[] r = new Role[6];
//
// // 把角色添加进团队内
// team.addMember(r, m1);
// team.addMember(r, m2);
// team.addMember(r, m3);
// team.addMember(r, s1);
// team.addMember(r, s2);
// team.addMember(r, s3);
// team.addMember(r, s4);
// int sumHurt = team.attackSum(r);
// System.out.println("队伍一共造成" + sumHurt + "伤害");
//
// // 创建团队类
// Team team1 = new Team();
// // 船舰角色数组
// team1.role = new Role[6];
//
// // 把角色添加进团队内
// team1.addMember1(m1);
// team1.addMember1(m2);
// team1.addMember1(m3);
// team1.addMember1(s1);
// team1.addMember1(s2);
// team1.addMember1(s3);
// team1.addMember1(s4);
//
// int sumHurt1 = team1.attackSum1();
// System.out.println("队伍一共造成" + sumHurt1 + "伤害");
MagicStick magicStick1 = new GreenStick();
MagicStick magicStick2 = new BlackStick();
Magicer magicer1 = new Magicer("基拉法师", 21, 10);
Magicer magicer2 = new Magicer("光鳞龙", 15, 5);
magicer1.setStick(magicStick1);
magicer2.setStick(magicStick2);
System.out.println(magicer1.getName() + "\t" + "年龄:" + magicer1.getAge() + "\t" + "初始攻击伤害:" + magicer1.attack());
System.out.println(magicer2.getName() + "\t" + "年龄:" + magicer2.getAge() + "\t" + "初始攻击伤害:" + magicer2.attack());
magicer1.practise(); // level = 10 + 1 + stick.fire() 目前是十月,所以是stick.fire() = 1
magicer2.practise(); // level = 5 + 1 + stick.fire() 目前是十月,所以是stick.fire() = 2
System.out.println(magicer1.getName() + "\t" + "年龄:" + magicer1.getAge() + "\t" + "修炼后的攻击伤害:" + magicer1.attack());
System.out.println(magicer2.getName() + "\t" + "年龄:" + magicer2.getAge() + "\t" + "修炼后的攻击伤害:" + magicer2.attack());
System.out.println("-----------------------------------------------------------------");
Soldier soldier1 = new Soldier("狂战士", 21, 200);
Soldier soldier2 = new Soldier("Ziph", 30, 150);
Weapon weapon1 = new Bolo();
Weapon weapon2 = new Pike("Ziph");
// soldier拿起武器
soldier1.setWeapon(weapon1);
soldier2.setWeapon(weapon2);
/** 武器感知solider
* 武器特殊属性:年龄大于18的拿刀+100伤害 反之+50
* 武器特殊属性:拿到同名矛+1000伤害,反之+25
* 一个solider只能拿一把武器,否则solider设置会乱套
* 不进行武器的soldier设置会导致武器的特殊属性没法计算.
*/
weapon1.setSoldier(soldier1);
weapon2.setSoldier(soldier2);
System.out.println(soldier1.getName() + "\t" + "年龄:" + soldier1.getAge() + "\t" + "佩戴了刀之后的攻击伤害:" + soldier1.attack());
System.out.println(soldier2.getName() + "\t" + "年龄:" + soldier2.getAge() + "\t" + "佩戴了矛之后的攻击伤害:" + soldier2.attack());
soldier1.practise();
soldier2.practise();
System.out.println(soldier1.getName() + "\t" + "年龄:" + soldier1.getAge() + "\t" + "佩戴了刀,加以修炼后的攻击伤害:" + soldier1.attack());
System.out.println(soldier2.getName() + "\t" + "年龄:" + soldier2.getAge() + "\t" + "佩戴了矛,加以修炼后的攻击伤害:" + soldier2.attack());
}
}
测试结果与区别
测试数据
狂战士拿刀后伤害为200+100(年龄刀)=300
Ziph拿同名矛后伤害为150+1000=1150
最终,Test测试结果如下,与上述预期一致.
需要注意的是狂战士佩戴刀之后的伤害与Ziph拿到同名矛之后的伤害与原作者给出的测试结果的区别.
原作者的测试数据
没有使用weapon的setSoldier函数.
原作者的测试结果:
假如佩戴了刀和矛,以Ziph的年龄和名字,其最终伤害应该是200+100(年龄刀)+1000(同名矛)=1300而非1200
假如佩戴了刀和矛,以狂战士的年龄和名字,其最终伤害应该是150+100(年龄刀)+25(不同名矛)=275,而非1150
错误原因:Pike中(这样写不管你叫啥,矛都跟你姓)
Bolo中(这个age怎么编译通过的我是没有理解)
这两个导致之前的setSoldier设置的s没有被使用,使得上述两个错误出现(原作者也没有使用weapon.setSoldier)
结语
最终还是要感谢原作者「何学长在奔跑」提供的思路与代码,谢谢!