- 面向對象編程
解決問題趟据,分解對象,行為术健,屬性汹碱,然后通過對象的關系以及行為的調用來解決問題。
對象:用戶荞估;
行為:登錄咳促、連接jdbc稚新、讀取數(shù)據(jù)庫
屬性:用戶名、密碼
Scala語言是一個完全面向對象編程語言等缀。萬物皆對象 - 函數(shù)式編程
解決問題時枷莉,將問題分解成一個一個的步驟,將每個步驟進行封裝(函數(shù))尺迂,通過調用這些封裝好的步驟笤妙,解決問題。
例如:請求->用戶名噪裕、密碼->連接jdbc->讀取數(shù)據(jù)庫
Scala語言是一個完全函數(shù)式編程語言蹲盘。萬物皆函數(shù) - 在Scala中函數(shù)式編程和面向對象編程融合在一起了。
方法基本語法
語法:
說明:
- def : 關鍵字膳音,表示聲明方法
- add:方法名召衔,根據(jù)業(yè)務進行取名
- 參數(shù)名稱在前 : 參數(shù)類型在后,多個參數(shù)用 , 分割
- 返回類型:若無返回類型 可定義為 Unit 或 無需定義
- 函數(shù)體:用于編寫的業(yè)務邏輯的語句塊
與java方法的區(qū)別:
- scala 可以將函數(shù)定義到任意位置祭陷,甚至在一個函數(shù)內(nèi)定義一個函數(shù)苍凛。
def main(args: Array[String]): Unit = {
def sayHello(){
print("hello")
}
sayHello // hello
}
- java 只能將方法定義在類中,不能定義在另一個方法中
方法的定義:
- 函數(shù)1:無參兵志,無返回值
def sayHello(){
print("hello")
}
- 函數(shù)2:無產(chǎn)醇蝴,有返回值
def main(args: Array[String]): Unit = {
println(sayHello) // hello
}
def sayHello():String={
"hello"
}
- 函數(shù)3:有參,無返回值
def main(args: Array[String]): Unit = {
sayHello("張三")
}
def sayHello(name:String){
println(s"你好想罕,$name 童鞋") // 你好悠栓,張三 童鞋
}
- 函數(shù)4:有參,有返回值
def main(args: Array[String]): Unit = {
println(sum(10,20)) // 30
}
def sum(x:Int,y:Int):Int={
x+y
}
- 函數(shù)5:多參按价,無返回值
def main(args: Array[String]): Unit = {
sum(10,20) // 30
}
def sum(x:Int,y:Int){
println(x+y) //30
}
- 在scala中函數(shù)可以不用加
return
用來標識返回值惭适,在scala中會以最后一個參數(shù)或表達式的結果作為返回值。
方法參數(shù)
可變參數(shù)
無論是 scala 還是 java 他們都支持 可變參數(shù)
java :使用 ...
來表示
scala:使用 *
來表示
案例:
def main(args: Array[String]): Unit = {
info("坤坤","唱","跳","Rap","籃球")
}
def info(name:String,hobby:String*):Unit={
println(s"我叫$name,我的愛好有${hobby.toList}") // 我叫坤坤,我的愛好有List(唱, 跳, Rap, 籃球)
}
可變參數(shù)底層實現(xiàn)都是一個數(shù)組或集合楼镐,所以直接遍歷可變參癞志。
def info(name:String,hobby:String*):Unit={
for (h <- hobby){
println(h)
}
}
唱
跳
Rap
籃球
使用 可變參數(shù)需要注意:
- 被定義成可變參數(shù)的參數(shù),需要放在參數(shù)列表最后鸠蚪。
- 一個方法中只能有一個可變參數(shù)今阳。
- 可變參數(shù)不能與帶名參數(shù)一起使用(后面會講)
帶參默認值
在程序開發(fā)中,往往有這樣的需求茅信,當某些值為null或0時盾舌,我們需要判斷,然后給它指定一個默認值蘸鲸。
如:不指定性別妖谴,就會使用默認的性別 'M'
def main(args: Array[String]){
info("坤坤",60)
}
def info(name:String,age:Int,sex:Char='M'){
println(s"姓名:$name,年齡:$age,性別:$sex") // 姓名:坤坤,年齡:60,性別:M
}
我們手動指定一個性別 'F'
def main(args: Array[String]){
info("坤坤",60,'F')
}
def info(name:String,age:Int,sex:Char='M'){
println(s"姓名:$name,年齡:$age,性別:$sex") // 姓名:坤坤,年齡:60,性別:F
}
至于語法:以這樣的形式sex:Char='M'
定義的參數(shù),就是表示給參數(shù)一個默認值。
常見錯誤寫法:
-
sex='M' :Char
:我有時候也不會搞錯膝舅,直到運行報錯才反應過來嗡载。 -
sex='M'
:這種形式的寫法也是錯誤的,必須指定類型仍稀。
帶名參數(shù)
以上面的案例說明洼滚;第一個參數(shù)為姓名
,第二個參數(shù)為年齡
技潘,第三個參數(shù)為性別
遥巴,一般情況下函數(shù)調用參數(shù),就按照函數(shù)定義時的參數(shù)順序一個個傳遞享幽。但是我們也可以通過指定函數(shù)參數(shù)名铲掐,并且不需要按照順序向函數(shù)傳遞參。
info(age=60,sex='F',name="坤坤")
def main(args: Array[String]){
info(age=60,sex='F',name="坤坤")
}
def info(name:String,age:Int,sex:Char='M'){
println(s"姓名:$name,年齡:$age,性別:$sex")
}
}
姓名:坤坤,年齡:60,性別:F
方法至簡原則(
)
- return 可以省略值桩,scala 會使用函數(shù)體的最后一行代碼作為返回值
def main(args: Array[String]): Unit = {
def say(context:String):String = {
context
}
print(say("hello")) // hello
}
- 如果函數(shù)體只有一行代碼摆霉,可以省略花括號
def main(args: Array[String]): Unit = {
def say(context:String):String = context
print(say("hello")) //hello
}
- 返回值類型如果能夠推斷出來,那么可以省略(:和返回值類型一起省略)
def main(args: Array[String]): Unit = {
def say(context:String)= context
print(say("hello")) // hello
}
- 如果有 return奔坟,則不能省略返回值類型携栋,必須指定。
def main(args: Array[String]): Unit = {
def say(context:String):String = return context
print(say("hello")) //hello
}
- 如果函數(shù)明確聲明 unit咳秉,那么即使函數(shù)體中使用 return 關鍵字也不起作用
def main(args: Array[String]): Unit = {
def say(context:String):Unit = return context
print(say("hello")) // ()
}
- scala 如果期望時無返回值類型刻两,可以省略等號
def main(args: Array[String]): Unit = {
def say(context:String) { print(context)}
say("hello") // hello
}
7.如果參數(shù)無參,但是聲明了參數(shù)列表滴某,那么調用時,小括號滋迈,可以不加霎奢。
def sayHello{print("hello")}
sayHello
- 如果函數(shù)沒有參數(shù)列表,那么小括號可以省略饼灿,調用時小括號必須省略
定義函數(shù):def sayHello{print("hello")}
掉用函數(shù):必須省略小括號 sayHello
- 如果不關心名稱幕侠,只關心邏輯處理,那么函數(shù)名稱(def)可以省略碍彭。這種聲明方式叫做 匿名函數(shù)(lambda 表達式)晤硕。
()=>{print("hello")}
總結:雖然很多簡化原則,但是不用去記庇忌,多敲就完了(我也記不住舞箍,沒事的時候,回顧一下筆記皆疹,知道個大概就行了疏橄。
函數(shù)的定義
語法
val 函數(shù)名 =(參數(shù)名:類型,...) => {函數(shù)體}
// 計算兩個數(shù)的和
val sum=(x:Int,y:Int)=>{
x+y
}
println(sum(2,3)) // 5
- 并不需要寫返回值,函數(shù)的返回值就是塊表達式最終返回代碼結果。
- 調用函數(shù)和調用方法是一樣的捎迫。
函數(shù)的簡化
- return 可以省略晃酒,scala 會使用函數(shù)體的最后一行代碼作為返回值
val sum=(x:Int,y:Int)=>{
x+y
}
- 如果函數(shù)體只有一行代碼,可以省略花括號
// 計算兩個數(shù)的和
val sum=(x:Int,y:Int)=> x+y
println(sum(2,3)) // 5
- 返回值類型如果能夠推斷出來窄绒,那么可以省略(:和返回值類型一起省略)
// 計算兩個數(shù)的和
val sum=(x:Int,y:Int)=> x+y
println(sum(2,3)) // 5
- 如果有 return贝次,則不能省略返回值類型,必須指定彰导。
函數(shù)中無法指定返回值蛔翅,至少我試了好幾次沒成功
- 如果函數(shù)明確聲明 unit,那么即使函數(shù)體中使用 return 關鍵字也不起作用
上面的都不行螺戳,這個也自然沒用了
- scala 如果期望時無返回值類型搁宾,可以省略等號
沒有等號,哈哈哈
- 如果參數(shù)無參倔幼,但是聲明了參數(shù)列表盖腿,那么調用時,小括號损同,可以不加翩腐。
val sayHello=()=>{
println("hello")
}
不行,無法調用膏燃;函數(shù)就是一個對象茂卦,sayHello 這是這個函數(shù)的引用,并不是調用组哩。
sayHello
打印一下該引用等龙,輸入的其實就內(nèi)存地址。
println(sayHello) // Demo02$$$Lambda$1/764977973@1fbc7afb
正確寫法
sayHello()
函數(shù)與方法的區(qū)別
官方函數(shù)的定義
- 函數(shù)的定義:
(x: Int) => x + 1
- 方法的定義:
def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3
函數(shù)與方法概念
- 方法就是函數(shù)伶贰,函數(shù)就是一個對象
scala> val sum=(x:Int,y:Int)=>{x+y}
sum: (Int, Int) => Int = $$Lambda$1032/841090268@778a1250
$$Lambda$1032/841090268@778a1250 就是 sum 函數(shù)的內(nèi)存地址蛛砰。
方法存在方法區(qū),對象存在堆內(nèi)存中黍衙。
- 函數(shù)調用必須帶上
()
泥畅,否則無法調用 - 方法寫在類中,方法是可以被重載琅翻,函數(shù)無法被重載
方法:
def main(args:Array[String]):Unit={
println(sum(1, 2)) // 3
println(sum(1, 2,4)) // 7
}
def sum(x:Int,y:Int):Int={
x+y
}
def sum(x:Int,y:Int,z:Int):Int={
x+y+z
}
但是在方法中不能重載
def main(args:Array[String]):Unit={
def sum(x:Int,y:Int):Int={
x+y
}
def sum(x:Int,y:Int,z:Int):Int={
x+y+z
}
println(sum(1, 2))
println(sum(1, 2,4))
}
Error:(7, 9) method sum is defined twice;
the conflicting method sum was defined at line 4:9
def sum(x:Int,y:Int,z:Int):Int={
對于函數(shù)位仁,無論是在類中,還在方法中方椎,都是不行的聂抢,因為函數(shù)需要定義變量名;變量名不能重復
辩尊。
val sum=(x:Int,y:Int)
val sum=(x:Int,y:Int,z:Int)
- 方法轉函數(shù):
方法名 _
def main(args:Array[String]):Unit={
val a=sum _
println(a(1,2,3))
}
def sum(x:Int,y:Int,z:Int):Int={
x+y+z
}
函數(shù)的另一種寫法
FunctionNum
:Num
表示0-22個數(shù)字涛浙。最多只有23種
Function0:表示0個參數(shù)
Function1:表示1個參數(shù)
Function10:表示10個參數(shù)
Function22:表示22個參數(shù)
依舊拿 sum
為例
val sum=(x:Int,y:Int)=>{
x+y
}
它有兩個參數(shù);所以使用 Function2
:
val sum2=new Function2[Int,Int,Int] {
override def apply(v1: Int, v2: Int) = v1+v2
}
Function2[Int,Int,Int] :
第一個Int:表示第一個參數(shù)的類型
第二個Int:表示第二個參數(shù)的類型
第三個Int:表示返回值的類型
需要重寫它的 apply
方法;在內(nèi)部做運行
override def apply(v1: Int, v2: Int)
如果代碼很多轿亮,是可以指定{}
將代碼包起來
override def apply(v1: Int, v2: Int) = {
v1+v2
}
對比一下原來的形式
// 計算兩個數(shù)的和
val sum1=(x:Int,y:Int)=>{x+y}
// Function* 的形式
val sum2=new Function2[Int,Int,Int] {
override def apply(v1: Int, v2: Int) = {
v1+v2
}
}
調用
println(s"sum1=${sum1(2,3)}") // 5
println(s"sum2=${sum2(4,5)}") // 9
結語:
對于scala目前處于學習階段疮薇,以上內(nèi)容都是我學習的總結,至于內(nèi)容質量我注,仁者見仁按咒,不好的大家提出來,相互進步但骨,能幫助你的励七,我也很高興。