Scala中的类和Object

Scala和java差不多定义类,使用class关键字

如下:

class CreateClassTest{

  //定义相应的类的字段(fileds)
  var sum = 0
  //定义一个私有的变量,在Scala中公开成员的方法是不显式指定任何访问修饰符。
  //换句话说,在Java中你可以说public,而在Scala中你什么都不说。Public是Scala的默认访问级别
  private var privateVar = "this is a private var"

  //定义相关的方法
  def add(str : String): String ={
    privateVar += str
    return privateVar
  }

  def check(str: String): Boolean ={
    if(privateVar.startsWith(str)) true else false
  }

//这个和上面的check是一样的效果

  def checkR(str: String): Boolean = if(privateVar.startsWith(str)) true else false

}

可以在类中创建类的字段和方法,定义方法使用def 方法名

var acc = new CreateClassTest
var csa = new CreateClassTest

上面两行是对类的引用,如果这里acc声明为val,不能重新分配一个新的对象
//acc.privateVar = "vister private var error"
//println(acc.privateVar)
//这里将报错,因为privateVar是私有的方法,只能在CreateClassTest类中进行访问

Scala中的分号规则:

  对于语句分离的准确规则,它们的工作效果非常简单。简而言之,除非满足下列条件之一,否则将行结尾视为分号:
 1.有问题的行以单词形式结束,该单词作为语句的结尾不合法,例如句点或中缀运算符 。
 2.下一行以一个无法启动语句的单词开头。
 3.该行在括号(...)或括号[...]内结束,因为它们无论如何都不能包含多个语句

Scala中的静态成员

Scala比Java更面向对象的一种方式是Scala中的类不能有静态成员。相反,Scala有单例对象。单例对象定义看起来像类定义,只不过您使用关键字object而不是关键字class

import scala.collection.mutable.Map

class CreateObjectTest{
  private var sum = 0
  def checksum(): Int = ~(sum & 0xFF) + 1
  def add(b: Byte){sum += b}
}

//创建一个静态成员

object CreateObjectTest{
  private val cache = Map[String, Int]()
  def calculate(str: String): Int=
    if(cache.contains(str))
      cache(str)
    else{
      val acc = new CreateObjectTest
      for(c <- str)
        acc.add(c.toByte)
      val cs = acc.checksum()
      cache += (str -> cs)
      cs
    }
}

当单例对象与类共享相同的名称时,它被称为类CreateObjectTest的companion对象。您必须在同一个源文件中定义类及其附属对象。该类被称为singleton对象的companion类。类和它的companion对象可以相互访问其私有成员
println(CreateObjectTest.calculate("hello world tony single object"))
然而,单例对象不仅仅是静态方法的持有者。它是一级对象。因此,可以将单例对象的名称看作是附加到该对象的名称标记
定义单例对象并不定义类型(在Scala抽象级别)。给定对象checksum累加器的定义,就不能创建checksum累加器类型的变量。相反,名为CreateObjectTest的类型是由singleton对象的companion类定义的。然而,单例对象扩展了一个超类,并且可以混合特征,类和单例对象之间的一个区别是单例对象不能接受参数,而类可以。因为不能用new关键字实例化单例对象,
所以无法向其传递参数。每个单例对象都是作为一个从静态变量引用的合成类的实例实现的,
因此它们具有与Java静态相同的初始化语义。特别是,单例对象是在一些代码第一次访问它时初始化的。
一个单例对象不与一个类共享相同的名称,称为独立对象

Scala的程序入口和java的一样,使用main方法,如下定义:

运行一个scala的应用,必须创建一个单例的对象与一个main方法,接受一个Array[String]的参数,
并且返回值为Unit的一个方法。和java基本类似,java为public static void main(String [] aegs){}

import CreateObjectTest.calculate   //引入其他的类

object Summer{
  def main(args: Array[String]){
    for(arg <- args)
      println(arg + " : " + calculate(arg))
  }
}

这里我们需要编译这两个类:CreateObjectTest.scala和Summer.scala

可以使用

1.scalac CreateObjectTest.scala Summer.scala

2.fsc CreateObjectTest.scala Summer.scala 如果出现下面的界面

之后就可以运行了:

scala Summer tony lovess

这将编译源文件,但是在编译完成之前可能会有明显的延迟。原因是每次编译器启动时,它都要花时间扫描jar文件的内容,并在查看提交给它的新源文件之前执行其他初始工作。出于这个原因,Scala发行版还包含一个名为fsc(用于快速Scala编译器)的Scala编译器守护进程.

第一次运行fsc时,它将创建一个本地服务器守护进程,该守护进程连接到计算机上的一个端口。然后,它将通过端口将要编译的文件列表发送给守护进程,守护进程将编译这些文件。下次运行fsc时,守护进程已经在运行了,因此fsc将简单地将文件列表发送给守护进程,该守护进程将立即编译文件。使用fsc,您只需要等待Java运行时第一次启动。如果您想停止fsc守护进程,可以通过fsc -shutdown来完成。运行这些scalac或fsc命令将生成Java类

如果我们不想写main这个方法,可以继承scala.Application这个类,但是这个类在scala版本2.9只有就已经过期了,改为App,如果在新版中使用Application的话,会包如下错误:

之后我们只需要将Applciation改为App,将能编译成功:

import CreateObjectTest.calculate

object FallWinterSpringSummer extends App {
  for(season <- List("fall","Winter","Spring"))
    println(season + " : " + calculate(season))
}

但是如果使用了App的话,将不能取得命令行中的参数,因为命令行参数在这种情况下不可用。其次,由于JVM线程模型中的一些限制,如果您的程序是多线程的,则需要显式main方法。最后,JVM的一些实现不优化由应用程序特征执行的对象的初始化代码。因此,只有当您的程序相对简单且单线程时,才应该从应用程序继承

猜你喜欢

转载自blog.csdn.net/qian1314520hu/article/details/85247890