Java(封装、继承、多态、接口)表示游戏中的角色练习题

针对如下文章部分代码进行了修改,使得逻辑上更加通顺,结果符合预期.
原文链接: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)
在这里插入图片描述


结语

最终还是要感谢原作者「何学长在奔跑」提供的思路与代码,谢谢!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值