Scala面向对象编程练习

Scala面向对象编程练习

1 类

  • 编写一个 Time 类,加入只读属性 hoursminutes,和一个检查某一时刻是否早于另一时刻的方法 before(other:Time):BooleanTime 对象应该以 new Time(hrs,min)方式构建。
class Time(val hrs:Int,val min:Int){
  val hours = hrs
  val minutes = min

  def before(other:Time): Boolean ={
    if(other.hours > this.hours){
      return true
    }
    if(other.hours == this.hours){
      if(other.minutes > this.minutes){
        return false
      }
    }
    return false
  }
}

  • 创建一个 Student 类,加入可读写的 JavaBeans 属性 name(类型为 String)和 id(类型为 Long)。有哪些方法被生产? (用 javap 查看。 )你可以在 Scala 中调用 JavaBeansgettersetter 方法吗?
class Student{
  @BeanProperty var id:Long = _
  @BeanProperty var name:String = _
}

javap -c 查看反编译代码:

C:\Users\lenovo>javap -c D:\AboutMyWork\IDEA-WorkSpace\ScalaDemo\ScalaExamples\target\classes\com\nefu\practice\Student.class
Compiled from "A_Class_2_Stundent.scala"
public class com.nefu.practice.Student {
  public long id();
    Code:
       0: aload_0
       1: getfield      #15                 // Field id:J
       4: lreturn

  public void id_$eq(long);
    Code:
       0: aload_0
       1: lload_1
       2: putfield      #15                 // Field id:J
       5: return

  public void setId(long);
    Code:
       0: aload_0
       1: lload_1
       2: putfield      #15                 // Field id:J
       5: return

  public java.lang.String name();
    Code:
       0: aload_0
       1: getfield      #24                 // Field name:Ljava/lang/String;
       4: areturn

  public void name_$eq(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #24                 // Field name:Ljava/lang/String;
       5: return

  public void setName(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #24                 // Field name:Ljava/lang/String;
       5: return

  public long getId();
    Code:
       0: aload_0
       1: invokevirtual #30                 // Method id:()J
       4: lreturn

  public java.lang.String getName();
    Code:
       0: aload_0
       1: invokevirtual #33                 // Method name:()Ljava/lang/String;
       4: areturn

  public com.nefu.practice.Student();
    Code:
       0: aload_0
       1: invokespecial #37                 // Method java/lang/Object."<init>":()V
       4: return
}

2 对象

  • 编写一个 Conversions 对象,加入 inchesToCentimeters,gallonsToLitersmilesToKilometers 方法
class Conversions{
  def inchesToCentimeters(inches:Double):Double={
    /*
    1英寸(in)=2.54厘米(cm)
     */
    2.54 * inches
  }

  def gallonsToLiters(gallons:Double):Double={
    /*
    1美制加仑(us gal)=3.7854118公升(l)
     */
    3.7854118 * gallons
  }

  def milesToKilometers(miles:Double):Double={
    /*
    1英里(mi)=1.609344千米(km)
     */
    miles * 1.609344
  }
}

  • 定义一个 Point 类和一个伴生对象,使得我们可以不用 new 而直接用 Point(3,4)来构造 Point 实例 apply 方法的使用
object Point {
  def apply(x: Int, y: Int): Point = new Point(x, y)
}
class Point(x:Int = 0,y:Int = 0){
}
  • 编写一个 Scala 应用程序,使用 App 特质,以反序打印命令行参数,用空格隔开。举例来说,scala Reverse Hello World 应该打印 World Hello
object B_Object_3_Reverse extends App {
  args.reverse.mkString(" ")
}
  • 编写一个扑克牌 4 种花色的枚举,让其 toString 方法分别返回♣,♦,♥,♠,并实现一个函数,检查某张牌的花色是否为红色
object Poker extends Enumeration {
  //scala里的类型,除了在定义class,trait,object时会产生类型,
  // 还可以通过type关键字来声明类型。
  type Poker = Value  //type相当于声明一个类型别名 用Poker代替Value类型

  val plumBlossom = Value("♣")
  val squarePiece = Value("♦")
  val hearts = Value("♥")
  val spades = Value("♠")

  def isRed(poker:Poker): Boolean ={
    poker == hearts || poker == squarePiece
  }

  override def toString(): String = {
    Poker.values.mkString(",")
  }
}
  • 练习使用包的各种声明方式,并查看他们的不同
class Statement{
  /*
  1.在 Scala 中, import 语句可以出现在任何地方,
  并不仅限于文件顶部。
   */
  /*
  2.在 Java 中如果想要导入包中所有的类,可以通过通配符星号,
   Scala 中采用下划线
   */
  import java.util._
  println(Math.random())

  /*
  3.如果不想要某个包中全部的类,而是其中的几个类,可以采用选取器(大括号)
   */
  import scala.collection.mutable.{HashMap}
   var map = new HashMap()
}
  • 编写一段程序,将 Java 哈希映射中的所有元素拷贝到 Scala 哈希映射。用引入语句重命名这两个类。
    import java.util.{HashMap=>JavaHashMap}
    import scala.collection.mutable.{HashMap=>ScalaHashMap}

    var jhm = new JavaHashMap[String,String]()
    var shm = new ScalaHashMap[String,String]()

    jhm.put("a","1");
    jhm.put("b","2");
    jhm.put("c","3");

    for(key <- jhm.keySet().toArray()){
      shm += (key.asInstanceOf[String] -> jhm.get(key))
    }

    println(shm.mkString(" "))

3 继承

  • 扩展如下的 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}
}

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

  • 扩展前一个练习的 BankAccount 类,新类 SavingsAccount 每个月都有利息产生
    (earnMonthlyInterest 方法被调用),并且有每月三次免手续费的存款或取款。在earnMonthlyInterest 方法中重置交易计数。
  override def deposit(amount:Double) = {
    if(this.monthlyCount < 4) {
      this.monthlyCount = this.monthlyCount + 1
      super.deposit(initialBalance)
    }else{
      super.deposit(initialBalance - 1)
    }
  }

  override def withdraw(amount:Double) = {
    if(this.monthlyCount < 4) {
      this.monthlyCount = this.monthlyCount + 1
      super.withdraw(initialBalance)
    }else{
      super.withdraw(initialBalance + 1)
    }
  }

  def earnMonthlyInterest(): Unit ={
    this.monthlyCount = 0
  }
  • 定义一个抽象类 Item,加入方法 pricedescriptionSimpleItem 是一个在构造器中给出价格和描述的物件。利用 val 可以重写 def 这个事实。 Bundle 是一个可以包含其他物件的物件。其价格是打包中所有物件的价格之和。同时提供一个将物件添加到打包当中的机制,以及一个适合的 description 方法
abstract class Item{
  def price():Double
  def description():String

  override def toString() {
    println("price is: " + price() + ", description is: " + description())
  }
}
class SimpleItem(val price:Double,val description:String) extends Item{

}
class Bundle extends Item {
  val items = new ArrayBuffer[Item]()
  def addItem(item: Item): Unit ={
    items += item
  }

  override def price(): Double = {
    var sumPrice:Double = 0d
    this.items.foreach(sumPrice +=  _.price())
    sumPrice
  }

  override def description(): String = {
    items.mkString(" ")
  }
}
  • 设计一个 Point类,其 x和 y坐标可以通过构造器提供。提供一个子类 LabeledPoint,其构造 器 接 受 一 个 标 签 值 和 x,y 坐 标 , 比 如 :new LabeledPoint( “BlackThursday” ,1929,230.07)
class Point(x:Double,y:Double){

}

class LabeledPoint(Label:String,x:Double,y:Double) extends Point{
}
  • 定义一个抽象类 Shape,一个抽象方法 centerPoint,以及该抽象类的子类 Rectangle和 Circle。为子类提供合适的构造器,并重写 centerPoint 方法
abstract class Shape{
  def centerPoint()
}

class Rectangle(long: Double,width:Double) extends Shape {
  override def centerPoint(): Unit = ???
}

class Circle(radius:Double) extends Shape {
  override def centerPoint(): Unit = ???
}
  • 提供一个 Square 类,扩展自 java.awt.Rectangle 并且是三个构造器:一个以给定的端点和宽度构造正方形,一个以(0,0)为端点和给定的宽度构造正方形,一个以(0,0)为端点,0 为宽度构造正方形
class Square(point:Point,width:Int) extends java.awt.Rectangle(point.x,point.y,width,width){
  def this(){
    this(new Point(0,0),0)
  }
  def this(width:Int){
    this(new Point(0,0),width)
  }
}

5 特质

object E_Trait_RenctangleLike {
  def main(args: Array[String]): Unit = {
    val egg = new Ellipse2D.Double(5,10,20,30) with RenctangleLike
    println("x = " + egg.getX + " y = " + egg.getY)
    egg.translate(10,-10)
    println("x = " + egg.getX + " y = " + egg.getY)
    egg.grow(10,20)
    println("x = " + egg.getX + " y = " + egg.getY)
  }
}

trait RenctangleLike{
  this:Ellipse2D.Double=>
  def translate(x:Double,y:Double){
    this.x = x
    this.y = y
  }
  def grow(x:Double,y:Double){
    this.x += x
    this.y += y
  }
}
x = 5.0 y = 10.0
x = 10.0 y = -10.0
x = 20.0 y = 10.0

6 类型参数

  • 定义一个不可变类 Pair[T,S], 带一个 swap 方法,返回组件交换过位置的新对偶
class Pair[T,S](val t:T,val s:S){
  def swap() = new Pair(s,t)
}
  • 定义一个可变类 Pair[T],带一个 swap 方法,交换对偶中组件的位置。
class Pairs[T](val t:T,val s:T){
  def swap() = new Pairs(s,t)
}
  • 给定类 Pair[T, S] ,编写一个泛型方法 swap,接受对偶作为参数并返回组件交换过位置的新对偶。
class Pairss[T,S](val t:T,val s:S){
  def swap(t:T,s:T) = new Pairss(s,t)
}
  • 编写一个泛型方法 middle,返回任何 Iterable[T]的中间元素。举例来说,middle(“World” )应得到’ r’
  def middle[T](iter:Iterable[T]):T={
    val array = iter.toArray
    array(array.length / 2)
  }
  • 给定可变类 Pair[S,T],使用类型约束定义一个 swap 方法,当类型参数相同时可以被调用。
class Pair[S,T](val s:S,val t:S){
  def swap(s:S,t:T): Unit ={
    if(s.getClass == t.getClass) new Pair(t,s)
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值