你好,我是一名新的编程学生。 我该如何计算x& y坐标?
问:示例:假设我们创建了一个模拟的程序 几种动物的运动 生物学研究。类鱼,青蛙和鸟 代表三种类型的动物 调查。
每个类都扩展了超类Animal,其中包含一个 方法移动并保持动物的当前位置为 x-y坐标。每个子类实现方法移动。
程序维护一个包含的Animal数组 引用各种Animal子类的对象。至 模拟动物的动作,程序发送每个 每秒对同一个消息对象 - 即移动。
每种特定类型的动物都会对此举动作出反应 消息以独特的方式:
鱼可能会游三英尺
青蛙可能跳五英尺
鸟可能飞十英尺。
程序向每个人发出相同的消息(即移动) 动物对象,但每个对象都知道如何修改它的x-y 适当地协调其特定的运动类型。
依靠每个物体知道如何“做正确的事” 响应相同的方法调用是关键概念 多态性。
sent发送给各种对象的相同消息“很多 形成“结果 - 因此术语多态性。
package animals;
public class Animals {
public static void main(String[] args) {
Fish F = new Fish ("fish");
Frog Fr = new Frog ("frog");
Bird B = new Bird ("bird");
Animal[] A = new Animal [3];
A[0]= F;
A[1]=Fr;
A[2]=B;
for (int i=0 ; i <3; i++){
A[i].toString();
}
}
}
package animals;
public abstract class Animal {
private String type;
public Animal (String type){
this.type = type ;
}
public abstract int move ();
public String toString (){
return String.format(type);
}
}
package animals;
public class Fish extends Animal {
public Fish (String name){
super(name);
}
@Override
public int move () {
//here what I write ?
}
@Override
public String toString (){
return String.format("Fish swim "+move()+" feet");
}}
我做所有这样的动物^^
答案 0 :(得分:0)
我在设计中看到了第一个问题。使用类型参数在专用类上声明构造函数时,就像在Fish类示例中所做的那样:
public Fish (String name){
super(name);
}
这将允许我以这种方式创建一个鱼的实例:
Fish salmon = new Fish("Parot");
虽然我没有任何编译时间或运行时错误,但这没有任何意义。相反,你应该像这样创建专门的类构造函数:
public Fish (){
super("Fish");
}
通过这种方式,您可以确定类型参数确实与鱼类相对应。现在,如果你想区分各种鱼类和各种鸟类或青蛙等,我建议你添加一个类似于类型的subType变量,并创建类的第二级专业化。示例:
// 2nd level of inheritance since Parot extents Bird and Bird extends Animal
public class Parot exents Bird {
public Parot() {
super ("Parot"); // Parot as a subType and not the type
}
}
现在回到你问的问题,是的,你应该保留对x和y位置变量的引用,你可以在Animal基类的级别上进行。我建议您将x和y指定为私有double,然后然后为x和y创建公共getter,但为它们创建受保护的setter,以便它们只能在Bird,Fish等专用类中进行修改强>,...
以下是我将如何修改基础Animal类
public abstract class Animal {
private String type;
private double x, y;
public double getX() {
return x;
}
public double getY() {
return y;
}
protected void setX(double x) {
this.x = x;
}
protected void setY(double y) {
this.y = y;
}
public Animal (String type){
this.type = type ;
}
public abstract int move ();
public String toString (){
return String.format(type);
}
public String position() {
return "[" + x + " , " + y + "]";
}
}
我添加了position()
方法,以便更好地显示动物的x,y位置。为了使其更逼真,您可以保留先前的位置并从旧位置计算新位置,但我会将此附加组件留给您。
现在我将如何修改Fish类。因为根据您的上述规格,鱼每次移动3英尺,这些信息可以存储在最终的静态变量中。然后我可以随机获取x的值,然后使用数学三角形标识来推导y值。
public class Fish extends Animal {
public final static int FISH_MOVE_LENGTH = 3;
public Fish (){
super("Fish");
}
@Override
public int move () {
Random r = new Random();
double xValue = r.nextInt(FISH_MOVE_LENGTH/2)+ 0.0D;
double yValue = Math.sqrt(FISH_MOVE_LENGTH*FISH_MOVE_LENGTH - xValue*xValue);
setX(xValue);
setY(yValue);
return (int)Math.sqrt(xValue*xValue + yValue*yValue);
}
@Override
public String toString (){
return String.format("Fish swim "+move()+" feet and its current position is " + position());
}}
我对其他专业化类使用了相同的方法,在三个类之间唯一改变的是public final static int FISH_MOVE_LENGTH = 3
,它将改变以反映您对每种动物的上述规范。
我还为您的Animal类添加了一些更改。首先随机选择要移动的动物,然后移动它并显示移动信息和新位置
我改为动物类的所有内容都是评论你的循环
// for (int i=0 ; i <3; i++){
// A[i].toString();
// }
并将其替换为
Random maestro = new Random();
while (true) {
int elementToPick = maestro.nextInt(3);
System.out.println(A[elementToPick]);
Thread.sleep(500);
}
Thread.sleep用于演示目的,允许我在各种显示之前经过一段时间,否则会过快。
以下是结果示例