scala语法
//包
//包申明
package cn.kgc.scalaoop.test01 //一个文件一个模块
package cn.kgc.scalaoop.test01{ //一个文件多个模块
作用域
}
//包对象:相当于类 => 作用域(相对小)
package object packobj{ //一个包多个模块
作用域
}
//类和对象
一个文件中只写一个类 => 类似于java
同一个文件中同名的class(伴生类)和object(单例伴生对象:运行时由虚拟机创建,程序人员直接使用)
//scala纯粹OOP,不支持static
//object(伴生对象):相当于给伴生类提供了静态成员
//伴生类和伴生对象之间可以互相访问私有属性
scala中文件
object 黄色o
class 蓝色c
class + object 上蓝下黄
classes + objects 灰色图标
scala class
访问修饰符
private
protected
public (默认)
属性
访问修饰符 var|val varName:Type = 初值
属性名称和构造参数名称不能相同
方法
方法的参数可以通过"="号赋默认值
返回值为方法体中最后一个表达式的结果,不使用return关键字
构造方法
一个主构造方法+n个辅助构造方法 :构成构造方法的重载
class ClassName(p1:Type1,...){}
辅助构造方法依赖主构造方法
class ClassName(p1:Type1,...){
def this(p1:Type1,...){ //构造方法){之间无=
}
def this(p1:Type1,...){ //构造方法){之间无=
}
}
自定义方法
方法是类的一部分
def methodName(param*:Type):ReturnType={方法体}
如果方法体只有一句话,则{}可以缺省
自定义函数
独立的对象:可以自由传递
//本质
class f extends Function2[Int,Int,Int]{
override def apply(v1: Int, v2: Int): Int = v1+v2
}
//应用
val f = (a:Int,b:Int)=>a+b:Int
函数可以作为方法的参数或返回值
def method(f:(Type1,...)=>ReturnType)=... //函数作为参数
def method():(Type1,...)=>ReturnType=... //函数作为返回值
调用method()(v1,...)
函数作为返回值的现象称之为柯里化
动态参数 params:Type*
带有动态参数的方法,其他参数不能有默认值
动态参数必须是最后一个
动态参数每传递一次增加一个维度
隐式参数
先创建隐式变量:implicit var|val VAR_NAME:Type = value
创建带隐式参数的函数
def method(v1:Type1,...)(implicit param:Type)=...
隐式函数
隐式函数参数
隐式转换
隐式类
扩展某指定类型/某执行类的功能
必须且只能有带有唯一参数的构造器,构造参数的类型决定了被扩展参数的类型
case class T()
implicit class Cal(v:Int){
def sqr()=v*v
def cub()=sqr()*v
}
implicit class Enc(v:String){
def enc()=v.map(x=>(x+1).toChar)
}
implicit class TExt(v:T){
def pow(a:Int,b:Int)=math.pow(a,b)
}
println(2.sqr())
println(2.cub())
println("abc".enc())
println(T().pow(3, 2))
泛型
参数化类型可变:必须继承关系的两个类 (多态)
参数化类型的泛化
协变 List[+A] 面向A的超类 返回值 类型放大
逆变 List[-A] 面向A的子类 参数 类型缩小
不变 [T]
闭包
方法内应用
//样例类:方便
case class Student(name:String,age:Int,gender:Char){
def me()=s"${name}\t${age}\t${gender}"
def show()=println(me)
}
val stu1 = Student("henry",18,'男')
stu1.show()
//普通类
class Stu(name:String,age:Int,gender:Char){
var _name:String = name
var _age:Int = age
var _gender:Char = gender
def me()=s"${_name}\t${_age}\t${_gender}"
def show()=println(me)
}
val stu2 = new Stu("henry",18,'男')
stu2.show()
备注:数据封装:首选元组(22列以内),其次样例类
业务封装:特质,抽象类,普通(伴生)类|伴生对象(静态成员和方法)|包对象(独立模块如工具类)
//继承和多态
class Type extends Single 单继承
class Type with Dao1 with Dao2 多混入
[+A]
//特质 trait
package cn.kgc.scalajdbc.oop04{
trait Dao[T]{
def exeUpdate(sql:String,params:Object*):Int
def exeQuery(sql:String,params:Object*):List[T]
}
trait Dao2
}
package cn.kgc.scalajdbc.oop05.stu {
case class Student(name:String,age:Int,gender:Char)
class StudentDao extends DaoBase with Dao[Student] with Dao2 {
override def exeUpdate(sql: String, params: Object*): Int = ???
override def exeQuery(sql: String, params: Object*): List[Student] = ???
}
object StudentDao extends Dao[Student] {
override def exeUpdate(sql: String, params: Object*): Int = ???
override def exeQuery(sql: String, params: Object*): List[Student] = ???
}
}
//动态混入
val fs = new FreeStudent() with Dao[Student]{
override def exeUpdate(sql: String, params: Object*): Int = ???
override def exeQuery(sql: String, params: Object*): List[Any] = ???
}
val fs2 = new FreeStudent()
实例1
package cn.kgc.scalajdbc.oop01{
class Test01(name:String="NONE",age:Int=0,gender:Char='男') {
var _name: String = name
var _age: Int = age
var _gender: Char = gender
def this(name: String, age: Int) {
this(name, age, '男')
}
def me(): String = s"${_name}\t${_age}\t${_gender}"
def show() = println(me)
def add(a:Int,b:Int):Int=a+b
def add(a:Int,b:Int,f:(Int,Int)=>Int):Int = f(a,b)
def add2(a:Int,b:Int)(f:(Int,Int)=>Int):Int = f(a,b)
def add():(Int,Int)=>Int = {
def a(a:Int,b:Int):Int = a+b
a
}
def add(arr:Array[Int])(implicit initVal:Int) = {
var rst:Int = initVal
for (elem <- arr) {
rst = rst + elem
}
rst
}
def cal(a:Int,b:Int)(implicit f:(Int,Int)=>Int):Int = f(a,b)
}
object Test01 {
}
}
实例1 Test
package cn.kgc.scalajdbc.oop01
object Test {
def main(args: Array[String]): Unit = {
val t1 = new Test01
implicit def add(a:Int,b:Int):Int = a/b
println(t1.cal(1, 2)(_-_))
}
}
实例2
package cn.kgc.scalajdbc.oop02{
class Test01(name:String="",age:Int=0,gender:Char=Test01.DEFAULT_GENDER) {
var _name:String = name
var _age:Int = age
var _gender:Char = gender
private val PRIVATE_KEY:String = "kb12redis"
def this(name:String,age:Int){
this(name,age,Test01.DEFAULT_GENDER)
}
def me()=s"${_name}\t${_age}\t${_gender}"
def show()=println(me)
}
object Test01{
private val public_key:String = "123456"
private val DEFAULT_GENDER:Char = '男'
println(new Test01().PRIVATE_KEY)
}
}
package cn.kgc.scalajdbc.oop03{
package object util{
val PI:Double = 3.14
def cal()=println("aa")
def cal(params:Int*)=params.sum
}
object util2{
val PI:Double = 3.14
def cal()=println("aa")
}
}
package cn.kgc.scalajdbc.oop04{
trait Dao[T]{
def exeUpdate(sql:String,params:Object*):Int
def exeQuery(sql:String,params:Object*):List[T]
}
trait Dao2
}
package cn.kgc.scalajdbc.oop05.com{
import java.sql.Connection
abstract class DaoBase{
def con():Connection={
null
}
}
}
package cn.kgc.scalajdbc.oop05.stu {
import cn.kgc.scalajdbc.oop04._
import cn.kgc.scalajdbc.oop05.com.DaoBase
case class Student(name:String,age:Int,gender:Char)
class StudentDao extends DaoBase with Dao[Student] with Dao2 {
override def exeUpdate(sql: String, params: Object*): Int = ???
override def exeQuery(sql: String, params: Object*): List[Student] = ???
}
object StudentDao extends Dao[Student] {
override def exeUpdate(sql: String, params: Object*): Int = ???
override def exeQuery(sql: String, params: Object*): List[Student] = ???
}
class FreeStudent
}
实例2 Test
package cn.kgc.scalajdbc.oop02
object Test {
case class T()
implicit class Cal(v:Int){
def sqr()=v*v
def cub()=sqr()*v
}
implicit class Enc(v:String){
def enc()=v.map(x=>(x+1).toChar)
}
implicit class TExt(v:T){
def pow(a:Int,b:Int)=math.pow(a,b)
}
abstract class Math[-T,+R]{
def func(t:T):R
}
class F(v:Int){var _v:Int = v;}
class S(v:Int) extends F(v:Int)
class G(v:Int) extends S(v:Int)
case class A(name:String,age:Int)
case class B()
class Add extends Math[S,S]{
override def func(t: S): S = new S(t._v*t._v)
}
class Collect[-A](a:A*){}
case class Student(name:String,age:Int,gender:Char){
def me()=s"${name}\t${age}\t${gender}"
def show()=println(me)
}
class Stu(name:String,age:Int,gender:Char){
var _name:String = name
var _age:Int = age
var _gender:Char = gender
def me()=s"${_name}\t${_age}\t${_gender}"
def show()=println(me)
}
def main(args: Array[String]): Unit = {
import scala.math._
import cn.kgc.scalajdbc.oop02.Test01
}
}
异常
package cn.kgc.scalajdbc.oop7
object ExceptionTest {
def main(args: Array[String]): Unit = {
try{
val arr = Array(1,2.0)
val ix = 1
if(ix>=arr.length){
throw new ArrayIndexOutOfBoundsException("index $ix out of bounds")
}
if(0==arr(1)){
throw new ArithmeticException("/by zero")
}
println(arr(0)/arr(1))
}catch{
case e:IndexOutOfBoundsException=>println(e.getMessage)
case e:ArithmeticException=>println(e.getMessage)
case _=> println("unkown error")
}finally {
println("finally")
}
Array(("henry",19,"male"),("jack",19),("pola",16,"female"),("ariel",8))
.collect({
case (a,b)=>s"$a\t$b"
case (a,b,"male")=>s"$a\t$b\tmale"
})
.foreach(println)
import scala.collection.mutable.Map
def cal1(a:Int,b:Int):Map[String,Any]={
val rst = Map[String,Any]()
if(0==b){
rst.put("exception",new ArithmeticException("/by zero"))
}else{
rst.put("result",a/b)
}
rst
}
def cal2(a:Int,b:Int):Option[Float]={
if(0==b){
Option.empty
}else{
Some(a*1.0f/b)
}
}
def cal3(a:Int,b:Int):Either[ArithmeticException,Float]={
if(0==b){
Left(new ArithmeticException("/by zero"))
}else{
Right(a*1.0f/b)
}
}
val value: Either[ArithmeticException, Float] = cal3(1, 2)
if(value.isLeft){
println(value.left.get)
}else{
println(value.right.get)
}
}
}