Scala作业5:对象&&继承

对象

1、编写一个Conversions对象,加入 inchesToCentimeters,gallonsToLiters 和 milesToKilometers 方法

以下是一个编写了 Conversions 对象的示例,其中包括了 inchesToCentimetersgallonsToLitersmilesToKilometers 方法:

object Conversions {
  def inchesToCentimeters(inches: Double): Double = {
    inches * 2.54
  }
  
  def gallonsToLiters(gallons: Double): Double = {
    gallons * 3.78541
  }
  
  def milesToKilometers(miles: Double): Double = {
    miles * 1.60934
  }
}

在上述代码中,Conversions 对象定义了三个静态方法:inchesToCentimetersgallonsToLitersmilesToKilometers。每个方法接受一个数值参数,并返回进行单位转换后的结果。

使用示例:

val inches = 10.0
val centimeters = Conversions.inchesToCentimeters(inches)
println(s"$inches inches is equal to $centimeters centimeters")

val gallons = 5.0
val liters = Conversions.gallonsToLiters(gallons)
println(s"$gallons gallons is equal to $liters liters")

val miles = 20.0
val kilometers = Conversions.milesToKilometers(miles)
println(s"$miles miles is equal to $kilometers kilometers")

运行上述示例代码将输出如下结果:

10.0 inches is equal to 25.4 centimeters
5.0 gallons is equal to 18.92705 liters
20.0 miles is equal to 32.1868 kilometers

这样,通过调用 Conversions 对象的方法,你可以进行英制单位到公制单位的转换。

2、定义一个 Point 类和一个伴生对象,使得我们可以不用 new 而直接用 Point(3,4)来构造 Point 实例 apply 方法的使用

下面是一个定义了 Point 类和伴生对象的示例,使得可以通过 Point(3, 4) 的方式来构造 Point 实例:

class Point(val x: Int, val y: Int)

object Point {
  def apply(x: Int, y: Int): Point = new Point(x, y)
}

在上述代码中,Point 类有两个属性 xy,并在构造函数中定义为 val,以便在类外部可以直接访问。

伴生对象 Point 中定义了一个 apply 方法。apply 方法是一个特殊的方法,当我们在对象后面跟上一对括号并传入参数时,会调用该方法。在本例中,Point(3, 4) 实际上是调用了 Point 伴生对象的 apply 方法,它返回一个新的 Point 实例。

使用示例:

val point = Point(3, 4)
println(s"x: ${point.x}, y: ${point.y}")

运行上述示例代码将输出如下结果:

x: 3, y: 4

通过定义伴生对象中的 apply 方法,我们可以使用 Point(3, 4) 的方式来构造 Point 实例,而无需显式使用 new 关键字。这种方式更加简洁和易读。

3、编写一个 Scala 应用程序,使用 App 特质,以反序打印命令行参数,用空格隔开。举例来说,scala Reverse Hello World 应该打印 World Hello

下面是一个使用 App 特质的 Scala 应用程序,以反序打印命令行参数并用空格隔开:

object Reverse extends App {
  // 反转命令行参数,并用空格隔开
  val reversedArgs = args.reverse.mkString(" ")

  // 打印反转后的结果
  println(reversedArgs)
}

在上述代码中,我们创建了一个名为 Reverse 的对象,并扩展了 App 特质。App 特质为我们提供了默认的 main 方法,可以直接在对象中编写代码,无需显式定义 main 方法。

argsApp 特质中自带的数组,包含了命令行传入的参数。我们使用 reverse 方法将其反转,然后使用 mkString 方法将数组元素用空格隔开形成一个字符串。

使用示例:
假设我们在命令行运行 scala Reverse Hello World,程序将输出:World Hello,这是反序后的结果。

4、编写一个扑克牌 4 种花色的枚举,让其 toString 方法分别返回♣,♦,♥,♠,并实现一个函数,检查某张牌的花色是否为红色

以下是一个实现扑克牌花色的枚举和检查红色花色的函数的示例代码:

object Suit extends Enumeration {
  type Suit = Value

  val Club: Suit = Value("♣")
  val Diamond: Suit = Value("♦")
  val Heart: Suit = Value("♥")
  val Spade: Suit = Value("♠")
}

def isRedCard(suit: Suit.Suit): Boolean = {
  suit == Suit.Diamond || suit == Suit.Heart
}

在上述代码中,我们定义了一个名为 Suit 的枚举,它继承自 Enumeration。我们通过为每个花色赋予一个值,并在值的构造函数中指定其对应的符号。这样,toString 方法就会返回对应的符号。

函数 isRedCard 接受一个 Suit.Suit 类型的参数 suit,并检查它是否为红色花色。我们通过比较 suit 是否等于 Suit.DiamondSuit.Heart 来判断。

使用示例:

val card1 = Suit.Club
val card2 = Suit.Diamond

println(card1.toString)  // 输出 ♣
println(card2.toString)  // 输出 ♦

println(isRedCard(card1))  // 输出 false
println(isRedCard(card2))  // 输出 true

在上述示例中,我们创建了两张牌,一个是梅花(Club),一个是方块(Diamond)。通过调用它们的 toString 方法,我们可以得到对应的符号。然后,我们调用 isRedCard 函数来检查花色是否为红色。

继承

1、扩展如下的BankAccount类,新类CheckingAccount对每次存款和取款都收取1美元的手续费

class BankAccount(initialBalance:Double){ 
private var balance = initialBalance 
   def deposit(amount:Double) = { 
		balance += amount; balance
	}
  def withdraw(amount:Double) = {
 		balance -= amount; balance} 
 	}

2、扩展前一个练习的BankAccount类,新类SavingsAccount每个月都有利息产生(earnMonthlyInterest方法被调用),并且有每月三次免手续费的存款或取款。在earnMonthlyInterest方法中重置交易计数。

以下是扩展了 BankAccount 类的 SavingsAccount 类的代码,新类每个月会产生利息,同时每个月有三次免手续费的存款或取款:

class BankAccount(initialBalance: Double) {
  protected var balance = initialBalance

  def deposit(amount: Double): Double = {
    balance += amount
    balance
  }

  def withdraw(amount: Double): Double = {
    balance -= amount
    balance
  }
}

class SavingsAccount(initialBalance: Double) extends BankAccount(initialBalance) {
  private val monthlyInterestRate = 0.01  // 月利率
  private val freeTransactionsPerMonth = 3  // 每月免手续费次数
  private var remainingFreeTransactions = freeTransactionsPerMonth  // 剩余免手续费次数

  def earnMonthlyInterest(): Unit = {
    val interest = balance * monthlyInterestRate
    balance += interest
    remainingFreeTransactions = freeTransactionsPerMonth
  }

  override def deposit(amount: Double): Double = {
    if (remainingFreeTransactions > 0) {
      remainingFreeTransactions -= 1
      super.deposit(amount)
    } else {
      super.deposit(amount - 1)  // 扣除1美元手续费
    }
  }

  override def withdraw(amount: Double): Double = {
    if (remainingFreeTransactions > 0) {
      remainingFreeTransactions -= 1
      super.withdraw(amount)
    } else {
      super.withdraw(amount + 1)  // 扣除1美元手续费
    }
  }
}

在上述代码中,我们定义了一个 SavingsAccount 类,它继承自 BankAccount 类。在 SavingsAccount 类中,我们添加了 monthlyInterestRate 变量来表示月利率,并添加了 freeTransactionsPerMonth 变量来表示每月免手续费的次数。还有一个 remainingFreeTransactions 变量来表示剩余的免手续费次数。

我们添加了一个 earnMonthlyInterest 方法,用于每个月计算利息并将其加入到余额中,然后重置剩余免手续费次数。

depositwithdraw 方法中,我们通过检查剩余免手续费次数来决定是否扣除手续费。如果剩余次数大于0,则不收取手续费,否则扣除1美元手续费。

使用示例:

val account = new SavingsAccount(1000)

println(account.deposit(200))  // 输出 1199(存入200美元,免手续费)
println(account.withdraw(50))  // 输出 1148(取出50美元,免手续费)

account.earnMonthlyInterest()  // 计算利息并重置交易计数

println(account.deposit(100))  // 输出 1247(存入100美元,免手续费)
println(account.withdraw(70))  // 输出 1176(取出70美元,免手续费)

在上述示例中,我们创建了一个初始余额为1000美元的 SavingsAccount 对象。然后,我们进行了几次存款和取款操作,并在每次操作后打印出最终的余额。注意,前两次操作都是免手续费的,而第三次存款和取款操作会扣除1美元的手续费。最后,我们调用了earnMonthlyInterest 方法来计算利息并重置交易计数。

3、设计一个Point类,其x和y坐标可以通过构造器提供。提供一个子类LabeledPoint,其构造器接受一个标签值和x,y坐标,比如:new LabeledPoint(“Black Thursday”,1929,230.07)

以下是设计的 Point 类和其子类 LabeledPoint 的代码:

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

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

在上述代码中,我们定义了 Point 类,它具有 xy 坐标作为构造器的参数,并提供了一个 toString 方法来打印点的坐标。

然后,我们定义了 LabeledPoint 类,它是 Point 类的子类。它额外接受一个 label 标签值作为构造器的参数,并通过调用父类的构造器来设置 xy 坐标。我们还重写了 toString 方法,以打印标签和点的坐标。

使用示例:

val point = new Point(3.14, 2.71)
println(point)  // 输出 (3.14, 2.71)

val labeledPoint = new LabeledPoint("Black Thursday", 1929, 230.07)
println(labeledPoint)  // 输出 Label: Black Thursday, Point: (1929.0, 230.07)

在上述示例中,我们创建了一个 Point 对象和一个 LabeledPoint 对象,并打印它们的字符串表示形式。

4、定义一个抽象类Shape,一个抽象方法centerPoint,以及该抽象类的子类Rectangle和Circle。为子类提供合适的构造器,并重写centerPoint方法

以下是定义的抽象类 Shape 及其子类 RectangleCircle 的代码:

abstract class Shape {
  def centerPoint: (Double, Double)
}

class Rectangle(val width: Double, val height: Double, val x: Double, val y: Double) extends Shape {
  override def centerPoint: (Double, Double) = (x + width / 2, y + height / 2)
}

class Circle(val radius: Double, val x: Double, val y: Double) extends Shape {
  override def centerPoint: (Double, Double) = (x, y)
}

在上述代码中,我们定义了抽象类 Shape,它具有一个抽象方法 centerPoint。然后我们定义了 RectangleCircle 两个子类,并提供了相应的构造器。

Rectangle 类中,我们重写了 centerPoint 方法,根据矩形的宽度、高度、以及左上角的坐标计算并返回中心点的坐标。

Circle 类中,我们同样重写了 centerPoint 方法,直接返回圆的中心点的坐标。

使用示例:

val rectangle = new Rectangle(5.0, 3.0, 1.0, 2.0)
println(rectangle.centerPoint)  // 输出 (3.5, 3.5)

val circle = new Circle(2.0, 0.0, 0.0)
println(circle.centerPoint)  // 输出 (0.0, 0.0)

在上述示例中,我们创建了一个矩形对象和一个圆对象,并打印它们的中心点坐标。

5、提供一个Square类,扩展自java.awt.Rectangle并且是三个构造器:一个以给定的端点和宽度构造正方形,一个以(0,0)为端点和给定的宽度构造正方形,一个以(0,0)为端点,0为宽度构造正方形

以下是扩展自 java.awt.RectangleSquare 类的代码:

class Square(x: Int, y: Int, width: Int) extends java.awt.Rectangle(x, y, width, width) {
  def this(width: Int) = this(0, 0, width)
  def this() = this(0, 0, 0)
}

在上述代码中,我们定义了 Square 类,它继承自 java.awt.Rectangle 类。我们提供了三个构造器来创建正方形对象。

第一个构造器接受给定的端点坐标 (x, y) 和宽度 width,并调用父类的构造器来创建正方形对象。

第二个构造器只接受宽度 width,将端点坐标设置为 (0, 0),并调用父类的构造器来创建正方形对象。

第三个构造器不接受任何参数,将端点坐标和宽度都设置为 0,并调用父类的构造器来创建正方形对象。

使用示例:

val square1 = new Square(2, 2, 4)
println(square1)  // 输出 java.awt.Rectangle[x=2,y=2,width=4,height=4]

val square2 = new Square(6)
println(square2)  // 输出 java.awt.Rectangle[x=0,y=0,width=6,height=6]

val square3 = new Square()
println(square3)  // 输出 java.awt.Rectangle[x=0,y=0,width=0,height=0]

在上述示例中,我们分别使用三个构造器创建了不同的正方形对象,并打印它们的字符串表示形式。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值