题!!!!!

65 阅读5分钟

image.png

(一) 案例背景

你正在设计一个二维游戏的界面,需要用很多的点来表示游戏中的角色。

设计一个Point类,其x和y可以通过构造器提供。

它有几个方法:

1. 方法1: 计算自己在哪个象限。 whereAmI():String

2. 方法2: 计算和坐标原点的距离。getDist():Double

3. 方法3: 计算与另一个点的距离。fromPoint(other:Point):Double

4. 方法4: 重写equals 判断是否是同一个点(x和y都相等就是同一个点)。

5. 方法5: 重写toString,更友好的输出点的信息。

再设计一个子类LabelPoint它来继承Point类,其构造器接收一个标签值和x,y坐标。

例如: New LabelPoint("black",1,2)

任务分析

我们需要创建一个新的文件来实现这个功能,类名和方法名我们这里都有了,那么就按照要求逐步来实现即可。

父类名:Point;

属性名:x,y

方法:whereAmI, getDist,fromPoint, equals, toString。

子类名:LabelPoint

属性:label。

 

(三)实现父类Point

  1. 实现构造器

【分析】类的名字已经确定了,他的两个属性名x,y也确定了。我们直接设置它们为double类型即可。

【编码如下】

package level02  
  
object class06 {  
  class Point(var x:Double, var y:Double) {  
  }  
  
  def main(args: Array[String]): Unit = {  
    val p1 = new Point(1,1)  
  }  
}
  1. 重写toString

【分析】toString方法重写之后,可以让println更加有意义。按照我们之前学习的方式去改写即可。

package level02  
  
object class06 {  
  class Point(var x:Double, var y:Double) {  
      
    override def toString: String = {  
      s"Point(${x}, ${y})"  
    }  
  }  
  
  def main(args: Array[String]): Unit = {  
    val p1 = new Point(1,1)  
    println(p1)  
  }  
}
  1. 重写equals

【分析】equals方法重写之后,可以判断两个点是否是同一个。

package level02  
  
object class06 {  
  class Point(var x:Double, var y:Double) {  
      
    override def equals(obj: Any): Boolean = {  
      val other = obj.asInstanceOf[Point]  
      this.x == other.x && this.y == other.y  
    }  
  
    override def toString: String = {  
      s"Point(${x}, ${y})"  
    }  
  }  
  
  def main(args: Array[String]): Unit = {  
    val p1 = new Point(1,1)  
    val p2 = new Point(1,1)  
    println(p1 == p2)  
       }  
}

4.实现3个方法判断方法

【分析】按照要求,完成whereAmI, getDist, fromPoint这三个方法。

package level02  
  
object class06 {  
  class Point(var x:Double, var y:Double) {  
    def whereAmI():String = {  
      if(x >0 && y >0){  
        "第1象限"  
      } else if(x>0 && y < 0){  
        "第4象限"  
      } else if(x<0 && y < 0){  
        "第3象限"  
      }else if(x<0 && y > 0){  
        "第2象限"  
      }  else {  
        "未知"  
      }  
    }  
    def getDist():Double = {  
       Math.sqrt( this.x * this.x + this.y * this.y )  
    }  
  
    def fromPoint(other:Point):Double = {  
      Math.sqrt( (this.x-other.x) * (this.x-other.x) + (this.y-other.y) * (this.y-other.y ) )  
    }  
  
}  
  
  def main(args: Array[String]): Unit = {  
    val p1 = new Point(1,1)  
    val p2 = new Point(1,1)  
    println(p1 == p2)  
    println(p1.whereAmI())  
    println(p1.getDist())  
    println(p1.fromPoint(p2))  
   }  
}

完整代码示例

package level02  // 声明包名,用于代码组织和隔离

// 单例对象,包含Point类和主方法
object class06 {

  // 定义Point类,表示二维坐标系中的点
  // 主构造器接收两个参数x和y,类型为Double(支持小数坐标)
  // 使用var修饰,说明x和y是可变属性(可通过对象直接修改)
  class Point(var x: Double, var y: Double) {

    // 方法1:判断当前点所在的位置(原点、坐标轴或象限)
    def whereAmI(): String = {
      // 先判断是否为原点(x和y都为0)
      if (x == 0 && y == 0) {
        "原点"
      }
      // 排除原点后,判断是否在x轴上(y=0)
      else if (y == 0) {
        "x轴上"
      }
      // 排除原点后,判断是否在y轴上(x=0)
      else if (x == 0) {
        "y轴上"
      }
      // 第一象限:x正方向,y正方向
      else if (x > 0 && y > 0) {
        "第1象限"
      }
      // 第二象限:x负方向,y正方向
      else if (x < 0 && y > 0) {
        "第2象限"
      }
      // 第三象限:x负方向,y负方向
      else if (x < 0 && y < 0) {
        "第3象限"
      }
      // 剩余情况:x正方向,y负方向(第四象限)
      else {
        "第4象限"
      }
    }

    // 方法2:计算当前点到坐标原点(0,0)的直线距离
    def getDist(): Double = {
      // 利用勾股定理:距离 = √(x² + y²)
      math.sqrt(x * x + y * y)
    }

    // 方法3:计算当前点与另一个点other之间的直线距离
    def fromPoint(other: Point): Double = {
      // 计算x坐标差的平方和y坐标差的平方
      val dxSquared = (x - other.x) * (x - other.x)  // (x1-x2)²
      val dySquared = (y - other.y) * (y - other.y)  // (y1-y2)²
      // 距离 = √[(x1-x2)² + (y1-y2)²]
      math.sqrt(dxSquared + dySquared)
    }

    // 重写equals方法:判断两个点是否为同一个点(x和y都相等)
    override def equals(obj: Any): Boolean = {
      // 先判断obj是否为Point类型,不是则直接返回false
      if (!obj.isInstanceOf[Point]) {
        false
      } else {
        // 将obj转换为Point类型,比较x和y是否相等
        val other = obj.asInstanceOf[Point]
        this.x == other.x && this.y == other.y
      }
    }

    // 重写toString方法:返回更友好的点信息字符串
    override def toString: String = {
      // 格式化输出,显示x和y的值
      s"Point(${x}, ${y})"
    }
  }

  // 主方法:程序入口,用于测试Point类的功能
  def main(args: Array[String]): Unit = {
    // 创建测试用的点对象
    val p1 = new Point(1, 1)       // 第一象限的点
    val p2 = new Point(1, 1)       // 与p1坐标相同的点
    val p3 = new Point(3, 4)       // 到原点距离为5的点
    val p4 = new Point(0, 0)       // 原点
    val p5 = new Point(-2, 3)      // 第二象限的点
    val p6 = new Point(0, 5)       // y轴上的点
    val p7 = new Point(-3, 0)      // x轴上的点
    val p8 = new Point(2, -1)      // 第四象限的点

    // 测试toString方法
    println(p1)               // 输出:Point(1.0, 1.0)

    // 测试equals方法
    println(p1 == p2)         // 输出:true(坐标相同)

    // 测试whereAmI方法
    println(p1.whereAmI())    // 输出:第1象限
    println(p4.whereAmI())    // 输出:原点
    println(p5.whereAmI())    // 输出:第2象限
    println(p6.whereAmI())    // 输出:y轴上
    println(p7.whereAmI())    // 输出:x轴上
    println(p8.whereAmI())    // 输出:第4象限

    // 测试getDist方法(到原点的距离)
    println(p3.getDist())     // 输出:5.0(3²+4²=25,开方后为5)

    // 测试fromPoint方法(两点间距离)
    println(p1.fromPoint(p3)) // 输出:3.60555...((3-1)²+(4-1)²=13,开方后约3.6055)
  }
}