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

第1部分:编写一个抽象的Human,实现上面的Human。您需要在您的项目中包含这个接口。第2部分:实现骑士和向导类。第3部分:编写一个名为LastNameWorld的测试程序,它:
第4部分:在你的模拟中增加第三个人类类(例如弓箭手,国王,王后,圣骑士等等)。这个类必须包含一个等于和一个克隆方法。将代码添加到测试工具中,以全面测试新类。
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());
}
}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();
}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;
}
}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;
}
}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;
}
}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;
}
}发布于 2016-11-29 10:50:58
您的代码结构很好。以下几点:
调用方法
无用强制转换
这些演员让我心烦:
//创建一个新骑士,这是第一个骑士人类2=((骑士)人类0).clone()的克隆;//检查这两个骑士是否相等,如果((向导)人类1).equals((向导)人类3.)){//.
克隆方法将克隆对象。不管它们的类型是什么,它们都会被克隆到同一个类中,不管是Wizard、Assassin还是其他什么。但是您不需要知道使用equals比较它们的确切类型,因为该方法只需要比较对象为Object。
这样做也是一样的:
// 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接口...如果该对象的类不实现接口Cloneable,则抛出CloneNotSupportedException。
因此,您需要决定由谁来执行这个函数( Human接口、抽象类或诸如此类),并使其扩展/实现cloneable。
equals 您对equals的声明是非正统的,并且可能不会执行您认为可能需要Override Object.equals(Object obj)方法的操作。现在,你的人类物体无法比较这些精灵。只有Assassin和Assassin,Wizard和Wizard等等,但没有Assassin和Wizard。
因此,当您调用assassin.equals(otherAssassin)时,您将调用您自己的函数Assassin.equals。但是当调用human.equals(otherHuman)时,您正在调用Object.equals(Object),它可能不太适合您,因为您没有覆盖它。这就是你需要早些投的原因..。现在你不会了!
我建议您通过使用双重调度集中处理通常的等于实现的繁琐部分(类型检查、空检查等),从而减少大量的样板:
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; }
}然后,每个具体类只需覆盖它们相应的方法:
public class Knight extends Human {
[...blah blah blah...]
@Override
public boolean equals(Knight knight){
[...your own implmentation here...]
}
}您知道,toString、clone、equals和hashCode是Object的方法,所以所有类都必须遵守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,他们的特殊技能是可用的,没有铸造!
这样读起来会更好:
// 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()!
一般来说,一个主要的方法应该仅仅是一个入口点,所以应该是
public static void main(String[] args) {
SomeObject business = new SomeObject(args); // instantiate somehow
business.start(); // Everything happens here, so it is reusable!
}CamelCase和诸如此类的都很好。
但是,必须使某些名称更加明确。我不明白:
public Knight(String n, int a, int hea, double hei, int xPos, int yPos, String hN) {尤其是。没有评论/Javadoc!这是一些人会有用的地方。
现在就这样!快乐编码
https://codereview.stackexchange.com/questions/148133
复制相似问题