(一) 案例背景
你正在设计一个二维游戏的界面,需要用很多的点来表示游戏中的角色。
设计一个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
- 实现构造器
【分析】类的名字已经确定了,他的两个属性名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)
}
}
- 重写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)
}
}
- 重写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)
}
}