【问题标题】:how I calculate xy coordinates?我如何计算 xy 坐标?
【发布时间】:2015-06-17 07:08:52
【问题描述】:

你好,我是一名新的编程学生。 如何计算 x&y 坐标??

问:  示例:假设我们创建一个程序模拟 几种动物的运动 生物学研究。鱼、蛙和鸟类 代表以下三种动物 调查。

 每个类都扩展了超类 Animal,它包含一个 方法移动并保持动物的当前位置为 x-y 坐标。每个子类都实现方法move。

 一个程序维护一个 Animal 数组,其中包含 对各种 Animal 子类的对象的引用。到 模拟动物的动作,程序发送每个 每秒对同一消息进行一次反对,即移动。

 每种特定类型的动物都会对移动做出反应 以独特的方式传达信息:

一条鱼可能会游三英尺

一只青蛙可能会跳五英尺

 一只鸟可能会飞十英尺。

 程序向每个人发出相同的消息(即,移动) 动物对象,但每个对象都知道如何修改它的 x-y 适合其特定的运动类型的坐标。

 依靠每个对象知道如何“做正确的事” 响应相同的方法调用是关键概念 多态性。

 发送到各种对象的同一消息具有“许多 结果的形式”——因此称为多态性。

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");
   }}

所有的动物我都这样^^

【问题讨论】:

  • 你说“......动物......它......将动物的当前位置保持为 xy 坐标。”,但我没有看到任何 xy 参考Animal 类;还有“鱼可能游三英尺”……这只是一个运动限制;谁决定鱼的实际移动位置?一些人工智能?
  • 应该创建 x 和 y 参考? :( 我该怎么做 move 方法?!

标签: java polymorphism abstract extends


【解决方案1】:

我在您的设计中看到了第一个问题。当您在具有类型参数的专用类上声明构造函数时,就像您在 Fish 类示例中所做的那样:

 public Fish (String name){
    super(name);
}

这将允许我以这种方式创建 fish 的实例:

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 指定为 private 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,它将根据您对每种动物的上述规范进行更改。

我还为您的 Animals 课程添加了一些更改。先随机选择要移动的动物,然后移动它并显示移动信息以及新的位置

我对 Animals 类所做的只是评论你的循环

//        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 用于演示目的,允许我在各种显示之前经过一段时间,否则会过快。

这是一个示例结果

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-23
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    相关资源
    最近更新 更多