Scala combines object-oriented and functional programming in one concise, high-level language. Scala’s static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.
给大家推荐一个在线的scala文档网站:https://static.runoob.com/download/Scala%E8%AF%AD%E8%A8%80%E8%A7%84%E8%8C%83.pdf
scala
//对 scala 的基本的程序结构说明
//1. object 是一个关键字,表示一个伴生对象
//2. 如果该文件只出现了一个 object HelloScala 就会在编译后两个.class 文件
//3. 第一个文件是 HelloScala.class 这个表示他的伴生类,但是空的.
//4. 第 2 个文件是 HelloScala$.class 对应的是 object HelloScala,但是本质是调用它对应的一个静态属性 MODULE$
//5. 这两个文件的关系和 main 函数的入口关系一会分析
object HelloScala {
// 1. def 表示一个方法或者一个函数
// 2. main 表示入口
// 3. args: Array[String] 表示形参,args 是形参名 Array[String] 是形参类型表示一个 Array 数组
// 4. :Unit 表示返回值类型为 Unit ,等价于 java 的 void
// 5. = 表示 后面写的是函数体/方法体, 它还有返回值类型推导的作用
def main(args: Array[String]):Unit = {
// 表示是 输出, 类似 System.out.println("hello, scala 世界!")
// 在 scala 语句后,不需要带; //体现简洁
println("hello, scala 世界!")
}
}
Any
是所有类的根类型,即所有类的父类(基类)
Scala
中类分为两个大的类型分支(AnyVal
[值类型,即可以理解成就是 java 的基本数据类型],AnyRef
类型)
AnyVal
虽然叫值类型,但是仍然是类(对象)
Scala
中有两个特别的类型(Null
), 还有一个是 Nothing
Null
类型只有一个实例 null
, 他是 bottom class
,是 AnyRef
的子类.
Nothing
类型是所有类的子类, 它的价值是在于因为它是所有类的子类,就可以将 Nothing
类型的对象返回给任意的变量或者方法,比如案例
scala
def f1():Nothing= { //表示 f1 方法就是没有正常的返回值,专门用于返回异常 throw new Exception("异常发生") }
Scala
中仍然遵守 低精度的数据自动的转成高精度的数据类型。
Scala
中,Unit
类型比较特殊,这个类型也只有一个实例 ()
数据类型 | 描述 |
---|---|
Byte | 8位有符号补码整数。数值区间为 -128 到 127 |
Short | 16位有符号补码整数。数值区间为 -32768 到 32767 |
Int | 32位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long | 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 |
Float | 32 位 IEEE 754标准的单精度浮点数 |
Double | 64 位 IEEE 754标准的双精度浮点数 |
Char | 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF |
String | 字符序列 |
Boolean | true或false |
Unit | 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。 |
Null | null 可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型 |
Nothing | Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。 |
Any | Any是所有其他类的超类 |
AnyRef | AnyRef类是Scala里所有引用类(reference class)的基类 |
在 Scala 当中,函数是一等公民,像变量一样,既可以作为函数的参数使用,也可以将函数赋值给一个变量. ,函数的创建不用依赖于类或者对象,而在 Java 当中,函数的创建则要依赖于类、抽象类或者接口。
当函数返回值被声明为 lazy 时,函数的执行将被推迟,直到我们首次对此取值,该函数才会执行。这种函数我们称之为惰性函数,在 Java 的某些框架代码中称之为懒加载(延迟加载),Java中没有原生方法。
lazy
不能修饰 var
类型的变量lazy
,会导致函数的执行被推迟,我们在声明一个变量时,如果给声明了 lazy
,那么变量值得分配也会推迟。 比如 lazy val i = 10
scala
object Demo1 {
def main(args: Array[String]): Unit = {
lazy val res = sum(1, 2, 3, 4, 6)
println(res) //使用res时,才会真正的开始计算
}
def sum(args: Int*): Int = {
var res = 0
for (n <- args) {
res += n
}
res
}
}
scala
def main(args: Array[String]): Unit = {
//scala 中去掉所谓的 checked(编译) 异常
//设计者认为,如果程序员编程时,认为某段代码可疑,就直接 try 并处理
//说明
//1. 如果代码可疑,使用 try 进行处理
//2. 在 catch 中,可以有多个 case ,对可能的异常进行匹配
//3. case ex: Exception => println("异常信息=" + ex.getMessage)
// (1) case 是一个关键字
// (2) ex: Exception 异常的种类
// (3) => 表明后的代码是对异常进行处理,如果处理的代码有多条语句可以{}扩起
//4. 在 scala 中把范围小的异常放在后面,语法不会报错,但是不推荐
//5. 如果捕获异常,代码即使出现异常,程序也不会崩溃。
try{
var n = 10 /0
}catch {
case ex:ArithmeticException=>{
println("异常:"+ex.getMessage)
}
case exception: Exception=>{
println(exception.getMessage)
}
}finally {
printf("完成")
}
}
Scala 提供了
throws
关键字来声明异常。可以使用方法定义声明异常。 它向调用者函数提供了此方法可能引发此异常的信息。 它有助于调用函数处理并将该代码包含在 try-catch 块中,以避免程序异常终止。在 scala 中,可以使用@throws
注释来声明异常
scala
@throws (classOf[ArithmeticException])
def function1(): Unit ={
var n = 10/0
}
scala
class 类名( 形参列表) { // 主构造器
// 类体
def this( 形参列表) { // 辅助构造器
}
def this( 形参列表) { // 辅助构造器可以有多个...
}
}
未用任何修饰符修饰
,那么这个参数是局部变量。val
关键字声明,那么 Scala 会将参数作为类的私有的只读属性使用var
关键字声明,那么那么 Scala 会将参数作为类的成员属性使用,并会提供属性对应的xxx()[类似 getter]/xxx_$eq()[类似 setter]方法,即这时的成员属性是私有的,但是可读写。JavaBeans 规范定义了 Java 的属性是像 getXxx()和 setXxx()的方法。许多 Java 工具(框架)都依赖这个命名习惯。为了 Java 的互操作性。将 Scala 字段加
@BeanProperty
时,这样会自动生成规范的 setXxx/getXxx 方法。这时可以使用 对象.setXxx() 和 对象.getXxx() 来调用属性。
@BeanPropetry
注解后,会生成 getXXX 和 setXXX 的方法scala
class Cat {
@BeanProperty var name: String = ""
@BeanProperty var age: Int = 0
@BeanProperty var color: String = ""
def this(name: String) {
this()
this.name = name
}
override def toString = s"Cat($name, $age, $color)"
}
private
为私有权限,只在类的内部和伴生对象中可用。protected
为受保护权限,scala 中受保护权限比 Java 中更严格 , 只能子类访问,问同包无法访问 (编译器从语法层面控制)。scala 设计者将访问的方式分成三大类: (1) 处处可以访问 public (2) 子类和伴生对象能访问 protected (3) 本类和伴生对象访问 private
scala
class Dog {
//import 可以放在任何的地方,同时他的作用范围就是{} 块中
//import 如果使用到 3 次及以上,则可以放在文件前面,否则可以使用就近引入.
import scala.beans.BeanProperty
@BeanProperty var name : String = ""
}
//Java 中如果想要导入包中所有的类,可以通过通配符*,Scala 中采用下 _
//如果不想要某个包中全部的类,而是其中的几个类,可以采用选取器,使用{} 括起来即可。
//如果有多个同名的类或者 trait 等,可以使用 scala 重命名的机制来解决.
import java.util.{ HashMap=>JavaHashMap, List}
//如果某个冲突的类根本就不会用到,那么这个类可以直接隐藏掉
import java.util.{ HashMap=>_, _} // 含义为 引入 java.util 包的所有类,但是忽略 HahsMap 类
Scala 明确规定, 重写一个非抽象方法需要用 override 修饰符,调用超类的方法使用 super 关键字
scala
def main(args: Array[String]): Unit = {
var student = new student
student.name = "michong"
student.num = "123123"
student.getInfo()
}
class person {
var name: String = _
def getInfo(): Unit = {
println("姓名:" + name)
}
}
class student extends person {
var num: String = _
override def getInfo(): Unit = {
super.getInfo()
println("学号:" + num)
}
}
基本介绍
要测试某个对象是否属于某个给定的类,可以用
isInstanceOf
方法。用asInstanceOf
方法将引用转换为子类的引用。classOf
获取对象的类名。
scala
var student:person = new student
student.name = "michong"
student.asInstanceOf[student].num = "123123"
override
关键字可省略 [原因:父类的抽象属性,生成的是抽象方法,因此就不涉及到方法重写的概念,因此 override
可省略]scala
abstract class person {
var name:String
}
class student extends person {
var name:String=""
}
scala
def main(args: Array[String]): Unit = {
//抽象类,他不能实例化,我们可以通过匿名子类的方式创建一个实例
val p = new person {
override var name: String = "123"
override def info(): Unit = {
println("test")
}
}
p.info()
}
abstract class person {
var name:String
def info()
}
}
object
关键字声明,伴生对象中声明的全是 “静态
“内容,可以通过伴生对象名称直接调用。public static final MODULE$
实现的。案例
scala
package cn.buildworld.scala.day2
object demo1 {
def main(args: Array[String]): Unit = {
val p1 = new Person("michong")
val p2 = new Person("qjzxzxd")
val p3 = new Person("米虫")
Person.joinGroup(p1)
Person.joinGroup(p2)
Person.joinGroup(p3)
Person.showInfo()
}
class Person(pname: String) {
var name: String = pname
}
object Person {
var num: Int = 0
def joinGroup(person: Person): Unit = {
num += 1
println(person.name + "--加入组织")
}
def showInfo(): Unit ={
println("当前"+num+"人")
}
def say(): Unit = {
println("Say Hi")
}
}
}
scala
trait 名 特质名 {
trait 体 体
}
1) trait 命名 一般首字母大写.
2) 在 scala 中,java 中的接口可以当做特质使用
trait使用
scala
#没有父类
class 类名 extends 质 特质 1 with 质 特质 2 with 质 特质 3 ..
#有父类
class 类名 extends 父类 with 质 特质 1 with 质 特质 2 with
scala
package cn.buildworld.scala.day2
object demo2 {
def main(args: Array[String]): Unit = {
val c = new C
c.getConnect("root","123456")
// 带有特质的对象,动态混入
val b = new B with Trait1{
override def getConnect(user: String, pwd: String): Unit = {
println("用户登录信息:user: "+user+" pwd: "+pwd)
}
}
b.getConnect("root","123456")
}
trait Trait1{
def getConnect(user:String,pwd:String): Unit
}
class A{}
class B extends A{}
class C extends A with Trait1{
override def getConnect(user: String, pwd: String): Unit = {
println("用户登录信息:user: "+user+" pwd: "+pwd)
}
}
class D{}
class E extends D with Trait1{
override def getConnect(user: String, pwd: String): Unit = {}
}
}
特质也是有构造器的,构造器中的内容由“字段的初始化”和一些其他语句构成。具体实现请参考“特质叠加”
1) 调用当前类的超类构造器 2) 第一个特质的父特质构造器 3) 第一个特质构造器 4) 第二个特质构造器的父特质构造器, 如果已经执行过,就不再执行 5) 第二个特质构造器 6) …….重复 4,5 的步骤(如果有第 3 个,第 4 个特质)
1) 调用当前类的超类构造 2) 当前类构造 3) 第一个特质构造器的父特质构造器 4) 第一个特质构造器. 5) 第二个特质构造器的父特质构造器, 如果已经执行过,就不再执行 6) 第二个特质构造器 7) ……重复 5,6 的步骤(如果有第 3 个,第 4 个特质)
scala
#在Logger中已经可以使用Exception中的相关的方法了
trait Logger{
this:Exception=>
def log()={
println(getMessage)
}
}
#使用MyLogger时先继承Exception类
class MyLogger extends Exception with Logger {}
scala
class AAA{
myOuter=>
class InnerAAA{
//使用别名的方式来访问外部类的属性和方法,相当于 myouter 是一个外部类的实例 AAA.this
//这时需要将外部类的属性和方法的定义/声明放在别名后
def test(innerAAA: InnerAAA): Unit ={
println(innerAAA)
println(myOuter.name)
println(myOuter.sal)
}
}
var name:String=_
private var sal:Double=_
}
隐式值也叫隐式变量,将某个形参变量标记为 implicit,所以编译器会在方法省略隐式参数的情况下去搜索作用域内的隐式值作为缺省参数
scala
package cn.buildworld.scala.day2
object demo5 {
def main(args: Array[String]): Unit = {
//隐式值
implicit val str1:String = "michong"
def hello(implicit name:String): Unit ={
println(name)
}
hello
}
}
scala
package cn.buildworld.scala.day2
object demo5 {
def main(args: Array[String]): Unit = {
val db = new MySql
db.add()
}
//隐式类
implicit class DB(val m :MySql){
def add(): Unit ={
println("添加")
}
}
class MySql{}
}
scala
package cn.buildworld.scala.day2
object demo4 {
def main(args: Array[String]): Unit = {
//隐式函数
implicit def addDelete(mySql: MySql):DB={
new DB
}
var db = new MySql
db.delete()
}
class MySql{}
class DB {
def delete(): Unit ={
println("删除数据!!!")
}
}
}