• Scala学习六——对象


    一.本章要点

    • 用对象作为但例或存放工具的方法
    • 类可以拥有一个同名的伴生对象
    • 对象可以扩展类或特质
    • 对象的apply方法通常用来构造伴生类的新实例
    • 如果不想显示定义main方法,可以扩展App特质的对象
    • 你可以通过扩展Enumeration对象来实现枚举

    二.单例对象

      Scala没有静态方法或静态字段,可以使用object语法结构达到同样的目的,对象定义了某个类的单个实例,包含了你想要的特性。 

      例:直接调用Accounts.newUniqueNumber()就可以创建一个新的唯一帐号,对象的构造器在该对象第一次被使用时调用,如果从未调用,则不会执行构造器。对象本质可以拥有类的所有特性,但是不能提供构造器参数。

    object Accounts{
    private var lastNumber=0
    def newUniqueNumber()={lastNumber+=1;lastNUmber}
    
    }

      

    三.伴生对象

      在Java/C++中,通常使用到既有实例方法又有静态方法的类,在Scala中就可以通过类和类同名的”伴生“对象来实现,例:

    class Account{
    val id=Account.newUniqueNumber()
    private var balance=0.0
    def deposit(account:Double){
    
    balance+=amount
    }
    }
    object Account{
    //伴生对象
    private var lastNumber=0
    private def newUniqueNumber()={lastNumber+=1;lastNumber}
    
    }

      注:类和它的伴生对象可以相互访问私有属性,但是需要存在于同一个源文件中;

        

    四.扩展类或特质的对象

      一个object可以扩展类以及一个或多个特质,其结果是一个扩展了指定类以及特质的类的对象,同时拥有在对象中给定的所有特性。

    五.apply方法

      通常会定义和使用apply方法,当遇到Object(参数1,...,参数N)时,apply方法会被调用(通常apply方法返回的是一个伴生类的对象),如Array对象定义了apply方法,Array(Array(1,7),Array(2,9))而不用构造器,可以更加方便,省去new。

      例:

    class Account private(val id:Int,initialBalance:Double){
    private var balance=initialBalance
    ...
    }
    object Account{
    //伴生对象
    def apply(initialBalance:Double)={
    
    new Account(newUniqueNumber(),initiaBalance)
    
    }
    
    
    }

    六.应用程序对象

    • 每个Scala程序都必须从一个对象的main方法开始,这个方法类型为Array[String]=>Unit;
    object Hello{
    def main(args:Array[String]){
    println("Hello")
    
    }
    
    }
    • 当然也可以扩展App特质,将程序代码放入构造器
    object Hello extends App{
    println("Hello")
    }
    • 如果需要命令参数,则可以通过args属性(应用设置scala.time[-Dscala.time]时程序退出会显示逝去的时间)
    object Hello extends App{
    if(args.length>0){
    println("Hello,"+args(0))
    else{
    println("Hello")
    }
    }
    
    }

      注:App特质扩展自另一个特质DelayedInit,编译器对该特质有特殊的处理。所有带该特质的类,其初始化方法都会被挪到delayedInit方法中(查看API可知Scala2.13.1已经弃除)App特质的main方法捕获到命令参数,调用delayedInit方法,并且可以根据要求打印逝去的时间。

    七.枚举

      和Java或C++不同,Scala并没有枚举类型,不过,标准库提供了一个Enumeration助手类,可以用于产出枚举。

      

    object TrafficLightColor extends Enumeration{
    val Red,Yellow,Green=Value
    }

      每次调用Value方法都返回内部类的新实例,该内部类也叫Value。

      也可以向Value传入ID,名称,或两个参数都传(如果不指定,则ID就会将前一个枚举基础上加一,从零开始,缺省名称为字段名)。

      注:通过TrafficLightColor.Red来引用枚举值(也可以直接import TrafficLightColor._直接应用),枚举的类型为TrafficLightColor.Value而不是TrafficLightColor(拥有这些值的对象);

         

         枚举值的ID通过id方法返回,名称通过toString方法返回。

         输出所有的枚举值:

     for(c <- TrafficLightColor.values  println(c.id+":"+c))

         通过ID或名称定位:

    TrafficLightColor(0) //调用Enumeration.apply
    TrafficLightColor.withName("Red")

    八.练习

       1.

    object Conversations {
      private val i2c: Double = 30.48
      private val g2l: Double = 3.785411784
      private val m2k: Double = 1.609344
    
      def inchesToCentimeters(inc: Double): Double = {
        inc * i2c
      }
    
      def gallonsToLiters(gal: Double): Double = {
        gal * g2l
      }
    
      def milesTokilometers(mil: Double): Double = {
        mil * m2k
      }
    
      def main(args: Array[String]): Unit = {
        println(inchesToCentimeters(10))
        println(gallonsToLiters(10))
        println(milesTokilometers(10))
      }
    }

       2.

    abstract class UnitConversion {
      def Converse(comn: Double): Double
    
    
    }
    
    object InchesToCentimeters extends UnitConversion {
      private val i2c: Double = 30.48
    
      override def Converse(comn: Double) = {
        i2c * comn
      }
    }
    
    object GallonsToLiters extends UnitConversion {
      private val g2l: Double = 3.785411784
    
      override def Converse(comn: Double): Double = {
        g2l * comn
      }
    }
    
    object MilesTokilometers extends UnitConversion {
      private val m2k: Double = 1.609344
    
      override def Converse(comn: Double): Double = {
        m2k * comn
      }
    }
    
    object Test {
      def main(args: Array[String]): Unit = {
        println(InchesToCentimeters.Converse(10))
        println(GallonsToLiters.Converse(10))
        println(MilesTokilometers.Converse(10))
      }
    
    }

       3.

       4.

       5.

       6.

       7.

       8.

  • 相关阅读:
    Windows Phone开发(13):如何规范用户的输入行为 转:http://blog.csdn.net/tcjiaan/article/details/7341513
    Windows Phone开发(10):常用控件(上) 转:http://blog.csdn.net/tcjiaan/article/details/7295060
    Windows Phone开发(11):常用控件(下) 转:http://blog.csdn.net/tcjiaan/article/details/7300085
    Windows Phone开发(9):关于页面状态 转:http://blog.csdn.net/tcjiaan/article/details/7292160
    Windows Phone开发(14):数据模板 转:http://blog.csdn.net/tcjiaan/article/details/7350849
    POJ 2975 Nim
    Codeforces Round #747 (Div. 2)
    POJ 2068 Nim
    CodeForces 126B Password
    A New Stone Game
  • 原文地址:https://www.cnblogs.com/lyq-biu/p/11948955.html
Copyright © 2020-2023  润新知