(一) 案例背景
你正在设计一个二维游戏的界面,需要用很多的点来表示游戏中的角色。
设计一个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。
[编码示范]
package level02
// Point.scala
/**
* Point类表示二维空间中的一个点
* @param x 点的x坐标
* @param y 点的y坐标
*/
class Point(val x: Double, val y: Double) {
/**
* 方法1:计算自己在哪个象限
* @return 象限描述字符串
*/
def whereAmI(): String = {
(x, y) match {
case (0, 0) => "原点"
case (0, _) => "y轴上"
case (_, 0) => "x轴上"
case (x, y) if x > 0 && y > 0 => "第一象限"
case (x, y) if x < 0 && y > 0 => "第二象限"
case (x, y) if x < 0 && y < 0 => "第三象限"
case (x, y) if x > 0 && y < 0 => "第四象限"
}
}
/**
* 方法2:计算和坐标原点的距离
* @return 到原点的距离
*/
def getDist(): Double = {
math.sqrt(x * x + y * y)
}
/**
* 方法3:计算与另一个点的距离
* @param other 另一个点
* @return 两点之间的距离
*/
def fromPoint(other: Point): Double = {
val dx = this.x - other.x
val dy = this.y - other.y
math.sqrt(dx * dx + dy * dy)
}
/**
* 方法4:重写equals方法,判断是否是同一个点
* @param obj 要比较的对象
* @return 如果x和y都相等则返回true
*/
override def equals(obj: Any): Boolean = obj match {
case that: Point =>
(this.x == that.x) && (this.y == that.y)
case _ => false
}
/**
* 方法5:重写hashCode方法,与equals保持一致
* @return 哈希码
*/
override def hashCode(): Int = {
val prime = 31
var result = 1
result = prime * result + x.hashCode
result = prime * result + y.hashCode
result
}
/**
* 方法6:重写toString,更友好的输出点的信息
* @return 点的字符串表示
*/
override def toString: String = {
s"Point(x = $x, y = $y)"
}
}
/**
* LabelPoint子类,继承Point类,带有标签的点
* @param label 点的标签
* @param x 点的x坐标
* @param y 点的y坐标
*/
class LabelPoint(val label: String, x: Double, y: Double) extends Point(x, y) {
/**
* 重写toString方法,包含标签信息
* @return 带标签的点的字符串表示
*/
override def toString: String = {
s"LabelPoint(label = '$label', x = $x, y = $y)"
}
/**
* 重写equals方法,包含标签比较
* @param obj 要比较的对象
* @return 如果标签、x和y都相等则返回true
*/
override def equals(obj: Any): Boolean = obj match {
case that: LabelPoint =>
(this.label == that.label) && super.equals(that)
case _ => false
}
/**
* 重写hashCode方法,包含标签
* @return 哈希码
*/
override def hashCode(): Int = {
val prime = 31
var result = super.hashCode()
result = prime * result + label.hashCode
result
}
}
// 测试对象
object PointTest extends App {
// 测试Point类
println("=== Point类测试 ===")
val p1 = new Point(3, 4)
val p2 = new Point(0, 0)
val p3 = new Point(-2, 3)
val p4 = new Point(3, 4)
println(s"p1: $p1")
println(s"p1所在位置: ${p1.whereAmI()}")
println(s"p1到原点的距离: ${p1.getDist()}")
println(s"p1到p2的距离: ${p1.fromPoint(p2)}")
println(s"p1和p4是否相等: ${p1 == p4}")
println(s"p1和p2是否相等: ${p1 == p2}")
println(s"p3: $p3, 所在位置: ${p3.whereAmI()}")
println("\n=== LabelPoint类测试 ===")
// 测试LabelPoint类
val lp1 = new LabelPoint("black", 1, 2)
val lp2 = new LabelPoint("red", 1, 2)
val lp3 = new LabelPoint("black", 1, 2)
println(s"lp1: $lp1")
println(s"lp1所在位置: ${lp1.whereAmI()}")
println(s"lp1到原点的距离: ${lp1.getDist()}")
println(s"lp1和lp2是否相等: ${lp1 == lp2}")
println(s"lp1和lp3是否相等: ${lp1 == lp3}")
println("\n=== 多态测试 ===")
val points: List[Point] = List(
new Point(1, 1),
new LabelPoint("blue", 2, 2),
new Point(-1, -1)
)
points.foreach { point =>
println(s"$point -> ${point.whereAmI()}")
}
}