首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生成RPG字符(对象)

生成RPG字符(对象)
EN

Code Review用户
提问于 2016-11-26 00:41:47
回答 1查看 3K关注 0票数 6

我是一个初学者Java程序员。我刚刚完成了一项任务,希望能对我的计划提出一些建议和/或建设性的批评。我正在努力确保我不会使用不良的做法来提高我的知识。对于上下文,我有任务的详细信息,后面是下面的完整代码:

第1部分:编写一个抽象的Human,实现上面的Human。您需要在您的项目中包含这个接口。第2部分:实现骑士和向导类。第3部分:编写一个名为LastNameWorld的测试程序,它:

  1. 宣称有4个人类
  2. 实例化骑士
  3. 实例化向导并移动它
  4. 克隆骑士并更改名称
  5. 检查骑士克隆是否与原始骑士不相等,如果等于:移动克隆
  6. 克隆向导
  7. 检查Wizard克隆是否等于原始向导,如果等于:移动克隆
  8. 印出生活在这个世界上的人类总数
  9. 将所有人类的描述(toString)打印到控制台

第4部分:在你的模拟中增加第三个人类类(例如弓箭手,国王,王后,圣骑士等等)。这个类必须包含一个等于和一个克隆方法。将代码添加到测试工具中,以全面测试新类。

主类

代码语言:javascript
复制
public class BakosWorld {

    public static void main(String[] args) {

        // Declare 4 humans
        Human[] humans = new Human[4];

        // Create original knight and wizard, then move wizard
        humans[0] = new Knight("Rob", 36, 100, 6.1, 50, 50, "Grey Wind");

        humans[1] = new Wizard("Gandalf", 32, 80, 5.11, 25, 25, 50);
        humans[1].move(45, 45);

        // Creating a new knight, that is a clone of the first knight
        humans[2] = ((Knight) humans[0]).clone();
        // Checks to see if the two knights are NOT equal
        if (((Knight) humans[0]).equals(((Knight) humans[2])) == false) {
            humans[2].move(85, 85);
        }

        // Creating a new wizard, that is a clone of the first wizard
        humans[3] = ((Wizard) humans[1]).clone();
        // Checks to see if the two knights ARE equal
        if (((Wizard) humans[1]).equals(((Wizard) humans[3]))) {
            humans[3].move(60, 60);
        }

        // Print information
        System.out.println("Number of humans: " + Human.getNumHumans());
        for (int i = 0; i < humans.length; i++) {
            System.out.println(humans[i].toString());
        }

        // Creating new human, assassin, the clone, and moving the clone
        Human arya = new Assassin("Arya", 16, 70, 5.9, 20, 20, 80);
        Human aryaClone = ((Assassin) arya).clone();

        if (((Assassin) arya).equals((Assassin) aryaClone)) {
            aryaClone.move(120, 120);
        }

        // Gandalf killed (original) Arya's father, so it's time for her to get her revenge
        ((Assassin) arya).inflictPoison(humans[1]);

        System.out.println("\n\n-UPDATED-\n\n" + arya.toString() + "\n"
                + aryaClone.toString() + "\n" + humans[1].toString());
    }
}

接口

代码语言:javascript
复制
public interface HumanInterface {

    //return the name of the human
    public String getName();

    //change the name of the human
    public void setName(String name);

    //get the age of the human
    public int getAge();

    //change the age of a human
    public void setAge(int a);

    //return the height of the human
    public double getHeight();

    //change the height of a human
    public void setHeight(double h);

    //return the health of a human
    public int getHealth();

    //change the health of a human
    public void setHealth(int h);

    //move a human
    public void move(int x, int y);

    //get Y position of a human
    public int getYPos();

    //get X position of a human
    public int getXPos();

    //return a string representation of a human object
    public String toString();
}

抽象类

代码语言:javascript
复制
abstract public class Human implements HumanInterface {

    protected String name;
    protected int age;
    protected double height;
    protected int health;
    protected int xPos;
    protected int yPos;

    private static int numHumans;

    public Human(String n, int a, int hea, double hei, int x, int y) {
        name = n;
        age = a;
        health = hea;
        height = hei;
        xPos = x;
        yPos = y;
        numHumans++;
    }

    public void move(int x, int y) {
        xPos = x;
        yPos = y;
    }

    public int getXPos() {
        return xPos;
    }

    public int getYPos() {
        return yPos;
    }

    public void setHealth(int h) {
        health = h;
    }

    public int getHealth() {
        return health;
    }

    public void setName(String n) {
        name = n;
    }

    public String getName() {
        return name;
    }

    public void setAge(int a) {
        age = a;
    }

    public int getAge() {
        return age;
    }

    public void setHeight(double h) {
        height = h;
    }

    public double getHeight() {
        return height;
    }

    public void setNumHumans(int n) {
        numHumans = n;
    }

    public static int getNumHumans() {
        return numHumans;
    }

    // General toString method
    public String toString() {
        String message;
        if (health <= 0) {
            message = "\n[HUMAN]"
                    + "\n" + name + " is dead.";
        } else {
            message = "xPos: " + xPos
                    + "\nyPos: " + yPos
                    + "\nName: " + name
                    + "\nAge: " + age
                    + "\nHealth: " + health
                    + "\nHeight: " + height;
        }
        return message;
    }
}

子类:骑士

代码语言:javascript
复制
public class Knight extends Human {

    private String horseName;

    public Knight(String n, int a, int hea, double hei, int xPos, int yPos, String hN) {
        super(n, a, hea, hei, xPos, yPos);
        horseName = hN;
    }

    public void setHorseName(String hN) {
        hN = horseName;
    }

    public String getHorseName() {
        return horseName;
    }

    // Clone the object
    public Knight clone() {
        Knight theClone;
        theClone = new Knight(this.name, this.age, this.health, this.height,
                this.xPos, this.yPos, horseName);
        return theClone;
    }

    // Check to see if 2 objects are the same
    public boolean equals(Knight k) {
        return k.age == this.age
                && k.name.equals(this.name)
                && k.health == this.health
                && k.height == this.height
                && k.xPos == this.xPos
                && k.yPos == this.yPos
                && k.horseName.equals(this.horseName);
    }

    // Knight toString method
    public String toString() {
        String message;
        if (health <= 0) {
            message = "\n[KNIGHT]"
                    + "\n" + name + " is dead.";
        } else {
            message = "\n[KNIGHT]"
                    + "\nxPos: " + xPos
                    + "\nyPos: " + yPos
                    + "\nName: " + name
                    + "\nAge: " + age
                    + "\nHealth: " + health
                    + "\nHorse Name: " + horseName
                    + "\nHeight: " + height;
        }
        return message;
    }
}

子类:向导

代码语言:javascript
复制
public class Wizard extends Human {

    private int magicka;

    public Wizard(String n, int a, int hea, double hei, int x, int y, int m) {
        super(n, a, hea, hei, x, y);
        magicka = m;
    }

    public void castSpell() {

    }

    public void setMagicka(int m) {
        magicka = m;
    }

    public int getMagicka() {
        return magicka;
    }

    // Clone the object
    public Wizard clone() {
        Wizard theClone;
        theClone = new Wizard(this.name, this.age, this.health, this.height,
                this.xPos, this.yPos, magicka);
        return theClone;
    }

    // Check to see if 2 objects are the same
    public boolean equals(Wizard w) {
        return w.age == this.age
                && w.name.equals(this.name)
                && w.health == this.health
                && w.height == this.height
                && w.xPos == this.xPos
                && w.yPos == this.yPos
                && w.magicka == this.magicka;
    }

    // Wizard toString method
    public String toString() {
        String message;
        if (health <= 0) {
            message = "\n[WIZARD]"
                    + "\n" + name + " is dead.";
        } else {
            message = "\n[WIZARD]"
                    + "\nxPos: " + xPos
                    + "\nyPos: " + yPos
                    + "\nName: " + name
                    + "\nAge: " + age
                    + "\nHealth: " + health
                    + "\nMagicka: " + magicka
                    + "\nHeight: " + height;
        }
        return message;
    }
}

子类:刺客

代码语言:javascript
复制
public class Assassin extends Human {

    int poison;

    public Assassin(String n, int a, int hea, double hei, int x, int y, int p) {
        super(n, a, hea, hei, x, y);
        poison = p;
    }

    public void inflictPoison(Human h) {
        h.setHealth(0);
        poison = this.poison - 20;
    }

    public void setPoison(int p) {
        poison = p;
    }

    public int getPoison() {
        return poison;
    }

    // Clone the object
    public Assassin clone() {
        Assassin theClone;
        theClone = new Assassin(this.name, this.age, this.health, this.height,
                this.xPos, this.yPos, poison);
        return theClone;
    }

    // Check to see if 2 objects are the same
    public boolean equals(Assassin a) {
        return a.age == this.age
                && a.name.equals(this.name)
                && a.health == this.health
                && a.height == this.height
                && a.xPos == this.xPos
                && a.yPos == this.yPos
                && a.poison == this.poison;
    }

    // Assassin toString method
    public String toString() {
        String message;
        if (health <= 0) {
            message = "\n[ASSASSIN]"
                    + "\n" + name + " is dead.";
        } else {
            message = "\n[ASSASSIN]"
                    + "\nxPos: " + xPos
                    + "\nyPos: " + yPos
                    + "\nName: " + name
                    + "\nAge: " + age
                    + "\nHealth: " + health
                    + "\nPoison: " + poison
                    + "\nHeight: " + height;
        }
        return message;
    }
}
EN

回答 1

Code Review用户

发布于 2016-11-29 10:50:58

您的代码结构很好。以下几点:

调用方法

之前的

无用强制转换

这些演员让我心烦:

//创建一个新骑士,这是第一个骑士人类2=((骑士)人类0).clone()的克隆;//检查这两个骑士是否相等,如果((向导)人类1).equals((向导)人类3.)){//.

克隆方法将克隆对象。不管它们的类型是什么,它们都会被克隆到同一个类中,不管是WizardAssassin还是其他什么。但是您不需要知道使用equals比较它们的确切类型,因为该方法只需要比较对象为Object

这样做也是一样的:

代码语言:javascript
复制
 // Creating a new knight, that is a clone of the first knight
humans[2] = humans[0].clone();
// Checks to see if the two knights ARE equal
if (humans[1]).equals(humans[3])) { //...

但是要想让它起作用,你需要有一个合适的equals和一个合适的clone方法.

Clonable接口

来自克隆()上的Java文档克隆()上的Java文档

...如果该对象的类不实现接口Cloneable,则抛出CloneNotSupportedException。

因此,您需要决定由谁来执行这个函数( Human接口、抽象类或诸如此类),并使其扩展/实现cloneable

正确地实现equals

您对equals的声明是非正统的,并且可能不会执行您认为可能需要Override Object.equals(Object obj)方法的操作。现在,你的人类物体无法比较这些精灵。只有AssassinAssassinWizardWizard等等,但没有AssassinWizard

因此,当您调用assassin.equals(otherAssassin)时,您将调用您自己的函数Assassin.equals。但是当调用human.equals(otherHuman)时,您正在调用Object.equals(Object),它可能不太适合您,因为您没有覆盖它。这就是你需要早些投的原因..。现在你不会了!

我建议您通过使用双重调度集中处理通常的等于实现的繁琐部分(类型检查、空检查等),从而减少大量的样板:

代码语言:javascript
复制
public abstract class Human implements HumanInterface {
    [...blah blah blah]
    public boolean equals(Object 
        if (other != null && other instanceof Human) {
            Human otherHuman = (Point) obj;
            return otherHuman.equals(this); // Order is important!
        }else{
            return false;
        }
    }

    // I like to provide default implementation, but at least one MUST be overriden
    public boolean equals(Knight knight){ return false; }
    public boolean equals(Wizard wizard){ return false; }
    public boolean equals(Assassin assassin){ return false; }

}

然后,每个具体类只需覆盖它们相应的方法:

代码语言:javascript
复制
public class Knight extends Human {
    [...blah blah blah...]
    @Override
    public boolean equals(Knight knight){
         [...your own implmentation here...]
    }
}

您知道,toStringcloneequalshashCodeObject的方法,所以所有类都必须遵守Object类定义的约定。你还有最后一个要编码..。

这也意味着public String toString();声明在HumanInterface中是无用的。

字符串处理

message = "\n刺客“+ "\nxPos:”+ xPos + "\nyPos:“+ yPos +”\n name:“+name+”+“\\nHealth:”+年龄+“\n health:”+health+“\n poison:”+yPos+ "\nHeight:“+高度”;

当连接多个StringBuilder时,请使用Strings,或者(这里更好)使用String.format,以使其更安全、更有效。

注释杂波

// Assassin toString方法公共字符串toString() {

//检查两个对象是否为相同的公共布尔值(Assassin a) {

这些注释没有带来任何东西,没有删除它,或者将它转换成一个适当的Javadoc。对toString来说,它可能毫无用处。

inflictPoison(Human h)需要一些。尤其是因为它能让poison变成阴性.而且还在工作。

存储人类

为什么要使用Array而不是List?你创造并杀死人类,这是有意义的。然后,当他们死后,你也可以使用remove()

那么计算它们就像list.size();一样简单

此外,我宁愿保持一个个人(正确的)参考他们每一个,S,他们的特殊技能是可用的,没有铸造!

这样读起来会更好:

代码语言:javascript
复制
 // Create original knight and wizard, then move wizard
 Knight rob = new Knight("Rob", 36, 100, 6.1, 50, 50, "Grey Wind");
 Wizard gandalf = new Wizard("Gandalf", 32, 80, 5.11, 25, 25, 50);
 rob.move(45, 45);

 // Creating a new knight, that is a clone of the first knight
 Knight robClone = rob.clone();
 // Checks to see if the two knights are NOT equal
 if (!rob.equals(robclone)) {
     robclone.move(85, 85);
 }

 // Creating a new wizard, that is a clone of the first wizard
 Wizard gandalfClone = gandalf.clone();
 // Checks to see if the two wizards ARE equal
 if (gandalf.equals(gandalfClone)) {
     gandalfClone.move(60, 60);
 }

 // [...]

 // Creating new human, assassin, the clone, and moving the clone
 Assassin arya = new Assassin("Arya", 16, 70, 5.9, 20, 20, 80);
 Human aryaClone = arya.clone();

 if (arya.equals(aryaClone)) {
     aryaClone.move(120, 120);
 }

 // Gandalf killed (original) Arya's father, so it's time for her to get her revenge
 arya.inflictPoison(gandalf);

 System.out.println("\n\n-UPDATED-\n\n" + arya.toString() + "\n"
            + aryaClone.toString() + "\n" + gandalf.toString());

利用您的BakosWorld

让它成为一个有用的对象,让它保存列表!然后在主目录中实例化一个World,并启动world.killEachOther()

一般来说,一个主要的方法应该仅仅是一个入口点,所以应该是

代码语言:javascript
复制
public static void main(String[] args) {
    SomeObject business = new SomeObject(args); // instantiate somehow
    business.start(); // Everything happens here, so it is reusable!
}

命名

CamelCase和诸如此类的都很好。

但是,必须使某些名称更加明确。我不明白:

代码语言:javascript
复制
    public Knight(String n, int a, int hea, double hei, int xPos, int yPos, String hN) {

尤其是。没有评论/Javadoc!这是一些人会有用的地方。

现在就这样!快乐编码

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/148133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档