一:面向对象编程
解决问题,分解对象,行为,属性,然后通过对象的关系以及行为的调用来解决问题
对象:用户
行为:登录、连接jdbc、读取数据库
属性:用户名、密码
二:函数式编程
解决问题时,将问题分解成一个一个的步骤,将每个步骤进行封装,通过调用这些封装好的步骤,解决问题。
eg:请求,用户名、密码,读取jdbc,读取数据库
三:函数基本语法
1:基本语法
2:案例
package chapter03
object TestFunction {
def main(args: Array[String]): Unit = {
def f (aegs : String):Unit = {
println(aegs)
}
f("hello world")
}
}
四:函数和方法的区别
1:概念
1:为完成某一功能的程序语句的集合,称为函数
2:类中的函数称之为方法
2:案例
package chapter03
import java.util.Date
object TestFunction {
// 方法可以进行重载和重写,程序可以执行
def main(): Unit = {
}
def main(args: Array[String]): Unit = {
// scala可以在任何的语法结果中声明任何的语法
new Date()
//函数没有重载和重写的概念,程序报错
def test():Unit = {
println("无参,无返回值")
}
test()
def test(name:String):Unit {
println()
}
// scala中函数可以嵌套定义
def test2():Unit ={
def test3(name:String):Unit ={
println("函数可以嵌套定义")
}
}
}
}
五:函数定义
package chapter03
object TestFunctionDeclare {
def main(args: Array[String]): Unit = {
// 无参,无返回值
def test1():Unit = {
println("无参,无返回值")
}
test1()
// 无参,有返回值
def test2():String = {
return "无参,有返回值"
}
println(test2())
// 有参,无返回值
def test3(s:String):Unit = {
println(s)
}
test3("jinlian")
// 有参,有返回值
def test4(s:String):String = {
return s+"有参,有返回值"
}
println(test4("hello "))
// 多参,无返回值
def test5(name:String,age:Int):Unit = {
println(s"$name,$age")
}
test5("dalang",40)
}
}
六:函数参数
package chapter03
object TestFunction2 {
def main(args: Array[String]): Unit = {
//可变参数
def test (s : String*):Unit ={
println(s)
}
//有输入参数,输出array
test("hello","scala")
//无输入参数,输出list()
test()
//如果参数列表中存在多个参数,那么可变参数一般放置在最后
def test2(name:String,s:String*):Unit = {
println(name + "," + s)
}
test2("jianlian","dalang")
//参数默认值
def test3(name:String,age:Int = 30):Unit ={
println(s"$name,$age")
}
//如果参数传递了值,那么会覆盖默认值
test3("jianlian",20)
//如果参数有默认值,在调用的时候,可以省略这个参数
test3("dalang")
//一般情况下,将有默认值的参数放置在参数列表的后面
def test4(sex:String = "男",name:String):Unit = {
println(s"$name,$sex")
}
//scala函数中参数传递是,从左到右
//test4("wusong")
//带名参数
test4(name = "ximenqing")
}
}
七:函数至简原则
1:原则
1:return 可以忽略,Scala会使用函数体的最后一行代码为返回值
2:如果函数体只有一行代码,可以省略花括号
3:返回值类型如果能够推断出来,那么可以忽略(和返回值类型一起省略)
4:如果有return,则不能省略返回值类型,必须指定
5:如果函数明确声明unit,那么即使函数体中使用return关键字也不起作用
6:Scala如果期望无返回类型,可以省略等号
7:如果函数无参,但是声明了参数列表,那么调用时,小括号,可以加可以不加
8:如果函数没有参数列表,那么小括号可以忽略,调用时小括号必须省略
9:如果不关心名称,只关心逻辑处理,那函数名def 可以忽略
2:案例
package chapter03
object TestFunction3 {
def main(args: Array[String]): Unit = {
// 标准函数写法
def f(s: String): String = {
return s + "jinlian"
}
println(f("hello"))
//return可以省略,Scala会使用函数体的最后一行代码作为返回值
def f1(s: String): String = {
s + "jinlian"
}
println(f1("hello"))
// 如果函数体只有一行代码,可以省略花括号
def f2(s:String):String = s + "jinlian"
// 返回值类型如果能够推断出来,那么可以省略,和返回值类型一起省略
def f3(s:String) = s + "jinlian"
println(f3("hello"))
// 如果有return,则不能省略返回值类型,必须指定
def f4():String = {
return "ximengqing"
}
println(f4())
// 如果函数明确声明unit,那么即使函数体中使用return关键字也不起作用
def f5():Unit = {
return "dalang"
}
println(f5())
//scala如果期望是无返回值类型,可以省略等号
//将无返回值的函数称之为过程
def f6(): Unit = {
"dalang6"
}
println(f6())
//如果函数无参,但是声明了参数列表,那么调用时,小括号,可以加可以不加
def f7() = "dalang"
println(f7())
println(f7)
//如果函数没有参数列表,那么小括号可以省略,调用时小i括号必须省略
def f8 = "dalang"
println(f8)
//如果不关心名称,只关心逻辑处理,那么函数名def可以省略
def f9 = (x:String)=>{println("wusong")}
def f10(f:String=>Unit) = {
f("")
}
f10(f9)
println(f10((x:String)=>{println(
"wusong"
)}))
}
}
八:高阶函数
1:函数可以作为值进行传递
package chapter03
object TestFunction4 {
def main(args: Array[String]): Unit = {
//调用foo函数,把返回值给变量f
val f= foo
//println(f) //输出1
//在被调用函数foo后面加上_,相当于把函数foo当成一个整体,传递给变量f1
val f1 = foo _
//foo() //输出foo...
//f1() //输出foo...
//如果明确变量类型,那么不适用下划线也可以将函数作为整体传递给变量
var f2:()=>Int = foo
println(f2())
}
def foo():Int = {
println("foo...")
1
}
}
2:函数可以作为参数进行传递
package chapter03
object TestFunction5 {
def main(args: Array[String]): Unit = {
//定义一个函数,函数参数还是一个函数签名,f表示函数名称,(Int,Int)表示输入两个Int参数,Int表示函数返回值
def f1(f:(Int,Int)=>Int):Int = {
f(2,4)
}
//定义一个函数,参数和返回值类型和f1的输入参数一致
def add(a:Int,b:Int):Int = a + b
//将add函数作为参数传递给f1函数,如果能够推断出来不是调用,_可以忽略
println(f1(add))
println(f1(add _))
}
}
3:函数可以作为函数返回值返回
package chapter03
object TestFunction6 {
def main(args: Array[String]): Unit = {
def f1() = {
def f2() = {
println("test")
}
f2 _
}
val f = f1()
//因为f1函数的返回值仍然为函数,所以可以变量f可以作为函数继续调用
f()
//上面的代码可以简化为
f1()()
}
}
九:匿名函数
1:没有名字的函数就是匿名函数
(x:Int)=> {函数体}
x:表示输入参数值,Int:表示输入参数类型,函数体:表示具体代码逻辑
2:案例
//定义一个匿名函数,并将它作为值赋给变量fun,函数有三个参数,类型分别为Int,String,Char,返回值类型为Boolean,要求调用函数fun(0,"",'0')得到的返回值为false,其他情况为true
val fun = (i:Int,s:String,c:Char) => {if (i==0 && s=="" && c=='0') false else true}
//定义一个函数func,它接收一个Int类型的参数,返回一个函数f1,它返回的函数f1,接收一个String类型的参数,返回一个函数f2,函数f2接收一个Char类型的参数,返回一个boolean的值
def func(i:Int):String=>(Char=>Boolean) = {
def f1(s:String):Char=>Boolean = {
def f2(c:Char):Boolean = {
if (i ==0 && s =="" && c =='0')false else true
}
f2
}
f1
}
def func1(i:Int):String=>(Char=>Boolean) = {
(s:String) => {
(c:Char) => {
if (i==0 && s=="" && c=='0') false else true
}
}
}
十:闭包和函数柯里化
1:闭包:如果一个函数,访问到了它的外部变量的值,那么这个函数和他所处的环境,成为闭包
2:函数柯里化:把一个参数列表的多个参数,变成多个参数列表
3:案例
package chapter03
object TestFunction8 {
def main(args: Array[String]): Unit = {
def add(a:Int,b:Int):Int ={
a + b
}
// 将固定加数作为另一个参数传入,但是是作为第一层参数传入
def addBy(a:Int):Int=>Int = {
def addB(b:Int):Int = {
a + b
}
addB
}
//内层函数用到外层函数的变量,闭包
// 柯里化
def addCurrying(a:Int)(b:Int):Int = {
a + b
}
}
}
十一:递归
package chapter03
object TestFunction9 {
def main(args: Array[String]): Unit = {
println(test(5))
def test(i: Int):Int = {
if (i == 1){
1
} else {
i * test(i - 1)
}
}
}
}
十二:抽象传递,抽象传值,抽象传名
package chapter03
object TestFunction10 {
def main(args: Array[String]): Unit = {
//传值参数
def f0(a:Int):Unit = {
println("a: " + a)
}
f0(23)
def f1():Int = {
println("f1调用")
12
}
f0(f1())
//传名参数,传递的是代码块
def f2(a: => Int):Unit = { //代码块的返回值为int
println("a: " + a)
println("a: " + a)
}
f2(f1()) // f1会执行两次,f1执行几次,取决于代码块赋给为a,a执行几次
}
}
十三:懒加载
1:当函数返回值被声明为lazy时,函数的执行将被推迟,直到我们首次对此取值,该函数才会执行。
2:案例
def main(args:Array[String]):Unit = {
lazy val res = sum(10,30)
println("-----------")
println("res=" + res)
}
def sum(n1:Int,n2:Int):Int = {
println("sum被执行..")
return n1 + n2
}
3:结果
输出结果
-----------
sum被执行...
res=40