Scala 面向对象编程实践:Point 类与 LabelPoint 子类实现

70 阅读2分钟

题目

(一)案例背景

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

设计一个 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 FinalsProject.teacher

/*
*  属性
*  方法
*
* */
object class01 {
  class Point(var x: Double, var y: Double) {
    def whereAmI():String = {
      if (x > 0 && y > 0) "第一象限"
      else "未知"
    }

    def getDist(): Double = {
      Math.sqrt(x * x + y * y)
    }

    def fromPoint(other:Point): Double = {
      val dx = x - other.x
      val dy = y - other.y
      Math.sqrt(dx*dx + dy*dy)
    }

    override def toString: String = {
      s"Point(${x}, ${y})"
    }

    override def equals(obj: Any): Boolean = {
      val other = obj.asInstanceOf[Point]

      other.x == x && other.y == y
    }
  }

  class LabelPoint(val label:String, x:Double, y:Double) extends Point(x, y){
    override def toString: String = {
      s"LabelPoint(${label},${x},${y})"
    }
  }

  def main(args: Array[String]): Unit = {
    val p1 = new Point(1, 1)
    val p3 = new Point(1, 1)
    val p2 = new Point(1, 2)
    println(p1.whereAmI())
    println(p1.getDist())
    println(p1.fromPoint(p2))
    println(p1 == p3)
    var p4 = new LabelPoint("black", 1, 2)
    println( p4.fromPoint(p2))
    println( p4)
  }
}

代码解析

Point 类解析

类定义与属性

class Point(var x: Double, var y: Double)
  • 定义 Point 类,包含两个可变属性 x 和 y
  • 使用 var 关键字表示这些属性是可变的
  • 通过构造器参数直接初始化属性

象限判断方法

def whereAmI():String = {
  if (x > 0 && y > 0) "第一象限"
  else "未知"
}
  • 根据 x 和 y 坐标的正负判断所在象限
  • 当前实现只判断了第一象限,其他情况返回"未知"

距离计算方法

def getDist(): Double = {
  Math.sqrt(x * x + y * y)
}
  • 使用勾股定理计算点到原点的距离
  • 公式:√(x² + y²)

两点间距离计算

def fromPoint(other:Point): Double = {
  val dx = x - other.x
  val dy = y - other.y
  Math.sqrt(dx*dx + dy*dy)
}
  • 计算当前点与另一个点之间的距离
  • 使用两点间距离公式:√((x₁-x₂)² + (y₁-y₂)²)

toString 方法重写

override def toString: String = {
  s"Point(${x}, ${y})"
}
  • 重写 toString 方法,提供友好的字符串表示
  • 使用字符串插值格式化输出

equals 方法重写

override def equals(obj: Any): Boolean = {
  val other = obj.asInstanceOf[Point]
  other.x == x && other.y == y
}
  • 重写 equals 方法判断两个点是否相等
  • 使用类型转换将 obj 转换为 Point 类型
  • 比较两个点的 x 和 y 坐标是否完全相同

LabelPoint 子类解析

类定义与继承

class LabelPoint(val label:String, x:Double, y:Double) extends Point(x, y)
  • LabelPoint 继承自 Point 类
  • 新增 label 属性用于标记点的类型
  • 继承父类的 x 和 y 坐标属性

toString 方法重写

override def toString: String = {
  s"LabelPoint(${label},${x},${y})"
}
  • 重写 toString 方法,在输出中包含标签信息
  • 格式化为 LabelPoint(标签,x坐标,y坐标)

测试代码解析

对象创建与测试

val p1 = new Point(1, 1)
val p3 = new Point(1, 1)
val p2 = new Point(1, 2)
  • 创建多个 Point 实例用于测试

方法调用测试

println(p1.whereAmI())  // 测试象限判断
println(p1.getDist())   // 测试到原点距离
println(p1.fromPoint(p2)) // 测试两点间距离
println(p1 == p3)       // 测试相等性判断

子类测试

var p4 = new LabelPoint("black", 1, 2)
println(p4.fromPoint(p2)) // 子类调用父类方法
println(p4)              // 测试子类 toString

总结

这个实现展示了 Scala 面向对象编程的核心概念:

  • 类的定义和构造器使用
  • 方法的定义和实现
  • 继承关系的建立
  • 方法重写(override)
  • 类型转换在 equals 方法中的应用
  • 字符串插值的使用