• Scala:类和对象


    类、字段、方法

    类是对象的蓝图,一旦定义了类,就可以用new关键字从蓝图创建对象。

    //给出下列定义
    class Cat {
    
    }
    
    //你就能创建Cat对象
    object Cat {
      val cat = new Cat
    }

    在类定义的时候,我们可以设定字段和方法,这也被称作成员。

    字段:用 val 或 var 定义,都是指向对象的变量,其中保留了对象的状态或者数据;

    方法:用 def 定义,内部包含了可执行代码,使用变量对对象多运算工作。

    在实例化类的时候,执行期的环境会设定一些内存来保存对象状态的镜像,即保存变量的内容。例如执行了下列操作

    1 //给出下列定义
    2 class Cat {
    3  var num=0
    4 }
    5 
    6 object Cat {
    7   val cat1 = new Cat
    8   val cat2 = new Cat
    9 }

    上面代码中,定义了一个类Cat,同时定义了一个var类型的变量num;

    然后对这个类进行了两次实例化操作。

    对象在内存的镜像大概如下:

    如果修改了num的值

     1 //给出下列定义
     2 class Cat {
     3  var num=0
     4 }
     5 
     6 //修改cat2的num值
     7 object Cat {
     8   val cat1 = new Cat
     9   val cat2 = new Cat
    10   cat2.num=3
    11 }

     对象在内存的镜像大概如下:

     

     虽然我们定义的:cat1、cat2是 val 类型的,但是里面的变量值的我们是可以修改的,只是你不能在将他们再次赋值为不同的对象,如

     1 //给出下列定义
     2 class Cat {
     3  var num=0
     4 }
     5 
     6 //修改cat2的num值
     7 object Cat {
     8   val cat1 = new Cat
     9   val cat2 = new Cat
    10   cat2.num=3
    11   cat2=new Cat //此处编译不通过
    12 }

     分号推断

    Scala程序中,语句末尾的分号通常是可选的。

    如果一行只有一个语句,可写可不写;

    如果一行有多个语句,则必须要写。

     1 object Cat {
     2   val cat1 = new Cat
     3 //  val cat2 = new Cat
     4 //  如果我们要实现 cat1.num+1
     5   cat1.num
     6   +1
     7 //  上面的语句会呗分成两个部分 cat1.num 和 +1  可以采用下面两种的方法将之合成一个整体
     8   (cat1.num
     9   +1)
    10 //  或者
    11   cat1.num+
    12   1  
    13 
    14 }

     用括号将之括起来或者将 “+” 放在行末,实际上,在Scala中,当你使用“+”这种中缀操作符的时候,操作符放在行尾才是Scala的普遍风格。

    分号推断规则:

    • 疑问行由一个不能合法作为语句结尾的字结束,如句点或上面所示的中缀操作符
    • 下一行开始的字是不能作为开始的字
    • 行结束于括号 "(...)" 方框 "[...]" 内部,因为这些符号不可能容纳多个语句

    上述三点除非有一点成立,否则语句末尾被认为是一个分号。

     Singleton 对象(单例对象)

    Scala 和 Java 相比,Scaa没有静态成员,而作为替代,Scala有单例对象:Singleton 对象。除了用 object 关键字替换了 class 之外,单例对象的定义就和累的定义一样。

    线面定义一个单例对象

     1 class ChecksumAccumulator {
     2   private var sum = 0
     3 
     4   def add(b: Byte) {
     5     sum += b
     6   }
     7 
     8   def checksum() = ~(sum & 0xFF) + 1
     9 }
    10 
    11 object ChecksumAccumulator {
    12 //  注:原文是 val类型的  但是后面的操作  cache += (s -> cs) 相当于重新指向一个新的对象 这是非法的
    13 //  private val cache = Map[String, Int]()
    14   private var cache = Map[String, Int]()
    15 
    16   def calculate(s: String): Int =
    17     if (cache.contains(s))
    18       cache(s)
    19     else {
    20       val acc = new ChecksumAccumulator
    21       for (c <- s)
    22         acc.add(c.toByte)
    23       val cs = acc.checksum()
    24       cache += (s -> cs)
    25       cs
    26     }
    27 }

    object ChecksumAccumulator 和 class  ChecksumAccumulator同名,

    object ChecksumAccumulator 称为 class  ChecksumAccumulator 的伴生对象:companion object

    class ChecksumAccumulator 称为 object ChecksumAccumulator  的伴生类:companion class

    类和单例对象的一个差别是:单例对象不带参数,而类可以,因为你不能用 new 关键字实例化一个单例对象,你没机会给它传递参数。

    每个单例对象都被作为一个有静态变量指向的虚构类:synthetic class 的一个实例来实现,因此他们和Java的静态类有着相同的初始化语法。

    不与伴生类共享名称的单例对象称为孤立对象:standalone object,在某些情况下会有到孤立对象,比如:把相关功能方法集中在一起或者定义一个Scala应用的入口。

    注:单例对象会在第一次被访问的时候初始化。

    注:你必须在一份源文件里面定义类和他的伴生对象。

     Scala 程序

    和Java类似,要执行一个Scala程序,需要提供一个包含main方法--一个仅带一个参数Array[String],而且结果类型为 Unit 的单例对象或估计对象名。任何带有合适签名的main方法的单例对象都可以作为程序的入口,如:

    1 import ChecksumAccumulator.calculate
    2 
    3 object Summer {
    4   def main(args: Array[String]): Unit = {
    5     for (arg <- args) {
    6       println(arg + ":" + calculate(arg))
    7     }
    8   }
    9 }

     和编译有两个方法:

    scalac ChecksumAccumulator.scala Summer.scala

    每次编译器启动时,需要花时间扫描jar文件内容。

    fsc ChecksumAccumulator.scala Summer.scala

    称为快速Scala编译器的后台服务,第一次执行 fsc时,会创建一个绑定你计算机端口上的本地服务后台进程,然后把文件列表通过端口发送到后台进行编译。
    下一次执行fsc时,后台进程已经在运行了,所以fsc将只是把文件列表发给后台进程,它会立刻开始编译。
    使用 fsc 只需在第一次等待 Java 运行环境启动。然后可以用 fsc -shutdown 来关闭
    上面的两个明亮将会创建 Java 类文件,然后可以用 scala 命令运行。此时需要调用包含正确 main 方法签名的单例对象或孤立对象名,如
    scala Summer of love
    of:-213
    love:-182

    此为本人 Scala 编程中文版 学习笔记

  • 相关阅读:
    [Maid] Write Tasks in Markdown with Maid
    [React] Preview and edit a component live with React Live
    [React] Build a slide deck with mdx-deck using Markdown + React
    [React] Spread Component Props in JSX with React
    重载new delete操作符是怎么调用的
    oracle如何设置show parameter显示隐含参数
    Google用户登录界面 Android实现
    Jquery 动态生成表单 并将表单数据 批量通过Ajax插入到数据库
    消息机4_B
    jQuery中对 input 控件的操作
  • 原文地址:https://www.cnblogs.com/lillcol/p/9844889.html
Copyright © 2020-2023  润新知