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的一些实现不优化由应用程序特征执行的对象的初始化代码。因此,只有当您的程序相对简单且单线程时,才应该从应用程序继承