今天首先完成了Scala编程的第二个实验。
实验内容:
2. 模拟图形绘制 对于一个图形绘制程序,用下面的层次对各种实体进行抽象。定义一个 Drawable 的特 质,其包括一个 draw 方法,默认实现为输出对象的字符串表示。定义一个 Point 类表示点, 其混入了 Drawable 特质,并包含一个 shift 方法,用于移动点。所有图形实体的抽象类为 主讲教师:林子雨 http://www.cs.xmu.edu.cn/linziyu 第 1 页厦门大学林子雨,赖永炫,陶继平 编著《Spark 编程基础(Scala 版)》 教材配套机房上机实验指南 实验 2 Scala 编程初级实践 主讲教师:林子雨 http://www.cs.xmu.edu.cn/linziyu 第 2 页 Shape,其构造函数包括一个 Point 类型,表示图形的具体位置(具体意义对不同的具体图 形不一样)。Shape 类有一个具体方法 moveTo 和一个抽象方法 zoom,其中 moveTo 将图形从 当前位置移动到新的位置, 各种具体图形的 moveTo 可能会有不一样的地方。zoom 方法实 现对图形的放缩,接受一个浮点型的放缩倍数参数,不同具体图形放缩实现不一样。继承 Shape 类的具体图形类型包括直线类 Line 和圆类 Circle。Line 类的第一个参数表示其位置, 第二个参数表示另一个端点,Line 放缩的时候,其中点位置不变,长度按倍数放缩(注意, 缩放时,其两个端点信息也改变了),另外,Line 的 move 行为影响了另一个端点,需要对 move 方法进行重载。Circle 类第一个参数表示其圆心,也是其位置,另一个参数表示其半 径,Circle 缩放的时候,位置参数不变,半径按倍数缩放。另外直线类 Line 和圆类 Circle 都混入了 Drawable 特质,要求对 draw 进行重载实现,其中类 Line 的 draw 输出的信息样式 为“Line:第一个端点的坐标--第二个端点的坐标)”,类 Circle 的 draw 输出的信息样式为 “Circle center:圆心坐标,R=半径”。如下的代码已经给出了 Drawable 和 Point 的定义, 同时也给出了程序入口 main 函数的实现,请完成 Shape 类、Line 类和 Circle 类的定义。 case class Point(var x:Double,var y:Double) extends Drawable{ def shift(deltaX:Double,deltaY:Double){x+=deltaX;y+=deltaY} } trait Drawable{ def draw(){println(this.toString)} } // 请完成 Shape 类、Line 类和 Circle 类的定义。 object MyDraw{ def main(args: Array[String]) { val p=new Point(10,30) p.draw; val line1 = new Line(Point(0,0),Point(20,20)) line1.draw line1.moveTo(Point(5,5)) //移动到一个新的点 line1.draw line1.zoom(2) //放大两倍 line1.draw val cir= new Circle(Point(10,10),5) cir.draw cir.moveTo(Point(30,20)) cir.draw cir.zoom(0.5) cir.draw } } 编译运行程序,期望的输出结果如下: Point(10.0,30.0) Line:(0.0,0.0)--(20.0,20.0) Line:(5.0,5.0)--(25.0,25.0) Line:(-5.0,-5.0)--(35.0,35.0) Circle center:(10.0,10.0),R=5.0源代码:
1 case class Point(var x:Double,var y:Double)extends Drawable 2 { 3 def shift(deltaX:Double,deltaY:Double) 4 { 5 x+=deltaX; 6 y+=deltaY 7 } 8 } 9 trait Drawable 10 { 11 def draw(){println(this.toString)} 12 } 13 abstract class Shape(var location:Point)//location是Shape的一个可变字段 14 { 15 def moveTo(newLocation:Point)//默认实现,只是修改位置 16 { 17 location=newLocation 18 } 19 def zoom(scale:Double) 20 } 21 class Line(beginPoint:Point,var endPoint:Point)extends Shape(beginPoint)with Drawable 22 { 23 override def draw() 24 { 25 println(s"Line:(${location.x},${location.y})--(${endPoint.x},${endPoint.y})")//按规定格式重载click 26 } 27 28 override def moveTo(newLocation:Point) 29 { 30 endPoint.shift(newLocation.x-location.x,newLocation.y-location.y)//直线移动时,先移动另外一个端点 31 location=newLocation //移动位置 32 } 33 34 override def zoom(scale:Double) 35 { 36 val midPoint=Point((endPoint.x+location.x)/2,(endPoint.y+location.y)/2) //求出中点,并按中点进行缩放 37 location.x=midPoint.x+scale*(location.x-midPoint.x) 38 location.y=midPoint.y+scale*(location.y-midPoint.y) 39 endPoint.x=midPoint.x+scale*(endPoint.x-midPoint.x) 40 endPoint.y=midPoint.y+scale*(endPoint.y-midPoint.y) 41 } 42 } 43 44 class Circle(center:Point,var radius:Double)extends Shape(center)with Drawable 45 { 46 override def draw() //按规定重载click 47 { 48 println(s"Circle center:(${location.x},${location.y}),R=$radius") 49 } 50 51 override def zoom(scale:Double) 52 { 53 radius=radius*scale //对圆的缩放只用修改半径 54 } 55 } 56 57 object MyDraw 58 { 59 def main(args:Array[String]) 60 { 61 val p=new Point(10,30) 62 p.draw 63 64 val line1=new Line(Point(0,0),Point(20,20)) 65 line1.draw 66 line1.moveTo(Point(5,5)) 67 line1.draw 68 line1.zoom(2) 69 line1.draw 70 71 val cir=new Circle(Point(10,10),5) 72 cir.draw 73 cir.moveTo(Point(30,20)) 74 cir.draw 75 cir.zoom(0.5) 76 cir.draw 77 } 78 79 }View Code
运行结果如图: