类和对象
class A{
//此处为类定义
} // 类
val a = new A //实例化 类A
//val 决定了不能再把 a 赋值给其他对象,但是 a 指向的内存中的对象是可以修改的。
// a 将始终指向 初始化的A对象。但对象包含的字段是可以修改的。
成员 是类 方法 和 字段 的统称。
字段 又名 实例变量 可以用 val
或者var
定义 作用:保留了对象的状态和数据。
方法 用 def
定义 作用 使用 字段进行对象的运算工作。
实例化类是,运行环境会预留一些内存来保留对象的状态映象——即:变量的内容。
私有字段
class A{
private val name: String = "aeiou"
}
/*
private 可以将字段 name 变为私有字段,禁止从类外部对其进行访问。 类似与python的两个前置下划线 __name
pulic 是scala 的默认访问级别。只要不特意声明private那么就是public的。谁都可以访问,和python一样
class A{
private var sum = 0
def add(b:Byte):Unit = { // scala中的参数都是val的。如果想在方法内部对其重新赋值,那么会报错
b = 10 // 这会报错
sum += b //你会发现这里没有return语句,因为如果没有任何的显示返回语句,scala方法,将会返回方法中最后一次计算的值。也就是 sum += 之后的值。这里会返回一个空值。因为 sum = sum+b 已经把sum+b 赋值给了sum。这个运算已经结束了,所以没得返回。如果想返回,相加之后的sum那么可以如下写法
}
}
object ClassStudy {// object 意思是伴生对象。
private var sum = 10
def ad(b:Int) :Int = { // 这里定义了返回值为Int
sum += b
sum // 这里 重新计算了sum
}
def main(args: Array[String]): Unit = { // main函数
val result = ad(10)
println(result)
}
}
或者这样写
object ClassStudy {
private var sum = 10
def ad(b:Int) :Unit = {//这种返回Unit的方法,执行的目的就是为了这个函数的副作用。
sum+=b
}
def main(args: Array[String]): Unit = {
ad(10) //这里调用了ad() 方法,利用了它的副作用——修改了sum 值。
println(sum)
}
}
如果某个计算结果仅仅计算单个结果表达式,那么可以去掉花括号,如果表达是很短,那么甚至可以把表达式和def写在同一行。如:
object ClassStudy {
private var sum = 10
def ad(b:Int) :Unit =
sum+=b // 去掉了或括号
def main(args: Array[String]): Unit = {
ad(10)
println(sum)
}
}
object ClassStudy {
private var sum = 10
def ad(b:Int) :Unit = sum += b // 写在了同一行
//或者 def ad(b:Int) :Unit = sum = sum+ b
def main(args: Array[String]): Unit = {
ad(10)
println(sum)
}
}
副作用 是指能够改变方法之外的某处状态,或执行I/O活动的方法
如果函数名和函数体之间没有=
号,那么默认返回的Unit 类型。
所有上述函数可以写为:
object ClassStudy {
private var sum = 10
def ad(b:Int) {sum = sum+ b} //这里省略了 = 号,已经默认的 返回类型Unit。
//回忆一下: def 方法本来就可以省略返回类型,因为scala编译器可以进行推断
def main(args: Array[String]): Unit = {//类似python的 if __name__ == '__main__' 程序的入口
ad(10)
println(sum)
}
}
scala
编译器可以把任何类型的值转换成Unit
类型,并丢弃原值。
如果一行里面仅有一条语句,那么可以省略分号;如果一行中有多条语句,那么;
必须要写。
Singleton对象【单例对象】
scala
不能定义静态成员,取而代之的是定义单例对象。除了object
代替了class
。单例对象的定义和类定义差不多。
上面就是单例对象的定义。
伴生对象/伴生类
当单例对象和某个类共享同一个名称时,它就被成为该类的伴生对象。类就被成为它的伴生类。类和伴生对象可以相互访问他们的私有变量。同时:类和伴生对象必须在同一个源文件中。
class ClassStudy{
private var mimima = 30
def add(c:Int):Int ={
ClassStudy.sum + c // 访问伴生对象的私有变量sum
}
}
object ClassStudy {
private var sum = 10
def ad(b:Int) {sum = sum+ b}
def main(args: Array[String]): Unit = {
ad(10)
println(sum)
val cs = new ClassStudy // new 只能实例化类,所以这里实例化的是ClassStudy类
println(cs.mimima) // 访问伴生类的私有变量 mimima
val result = cs.add(100)
println(result)
}
}
单例对象也是对象。因此单例的名字,可以被看作是贴在对象的名签 (感觉和python差不多啊)
类和对象的差别:
单例对象不带参数,每个单列对象都是虚构类的实例,并指向静态变量。单例对象只有第一次被访问时才会初始化
不与伴生类同名的单例对象成为 独立对象
Java
要求将公共类放到以这个类命令的的源文件中 --如:类A
放到A.java
文件中,但是scala
没有这个规定,类名和文件名可以不同。但是推荐像 Java
一样,用包含的类名命名文件。