繼承
定義一個(gè)抽象類,需要使用關(guān)鍵字abstract
定義一個(gè)抽象類得抽象方法,不需要關(guān)鍵字,只要把方法體空著
抽象類中定義得字段,沒有給初始值得就是抽象字段,但必須聲明類型。
abstract class Car{ //是抽象類,不能直接被實(shí)例化
val carBrand:String //字段沒有初始值,就是一個(gè)抽象得字段
def info() //抽象方法,不需要使用abstract關(guān)鍵字
def greeting()=println("welcome to my car!")
}
abstract class person{
var name:String
val age:Int
def show:Int
}
class BMWcar extends Car{
override val carBrand = "BMW" //重寫超類字段,需要使用override關(guān)鍵字,否則編譯會(huì)出錯(cuò)
def info():Unit = println("This is a %s car.It is on sale",carBrand) //重寫超類得抽象方法時(shí),不需要使用override關(guān)鍵字,不過如果加上override編譯也不錯(cuò)報(bào)錯(cuò)
override def greeting():Unit =println("Welcome to my BMW car!") //重寫超類的非抽象方法,必須使用override關(guān)鍵字
}
class BYDCar extends Car {
override val carBrand = "BYD" //重寫超類字段,需要使用override關(guān)鍵字,否則編譯會(huì)報(bào)錯(cuò)
def info():Unit = printf("This is a %s car. It is cheap.", carBrand)} //重寫超類的抽象方法時(shí),不需要使用override關(guān)鍵字,不過,如果加上override編譯也不錯(cuò)報(bào)錯(cuò)
override def greeting():Unit = println("Welcome to my BYD car!") //重寫超類的非抽象方法,必須使用override關(guān)鍵字
}
函數(shù)
//定義無輸入值的函數(shù)
def hi = "hi"
def hi:String = "hi"
def multiplier(x:Int, y:Int):Int = {x*y}
def safeTrim(s:String):String = {
if (s == null) return null
s.trim()
} //來判斷輸入值是否是非null
過程
沒有返回值的函數(shù),以一個(gè)語句結(jié)尾的函數(shù)也是一個(gè)過程。如果一個(gè)函數(shù),沒用顯式的返回類型,而且最后是一個(gè)語句,scala編譯器就會(huì)推導(dǎo)出這個(gè)函數(shù)的返回類型為Unit,表示沒用值,對(duì)于超過一行的過程,可以顯示指定類型Unit。
def log(d:Double) = println(f"Got value $d%.2f") //隱式的返回類型
def log(d:Double) : Unit = println(f"Got value $d%.2f") //顯式的返回類型
def log(d:Double) {println(f"Got value $d%.2f")} //這種寫法已經(jīng)廢棄了,會(huì)報(bào)警告
用空括號(hào)定義函數(shù)
定義和調(diào)用一個(gè)無輸入的函數(shù)。
def hi():String = "hi"
hi()
hi
反之,在定義時(shí)沒用加()。scala就不允許在調(diào)用時(shí)增加()。
使用函數(shù)表達(dá)式調(diào)用函數(shù)
def formatEuro(amt:Double) = f"$amt%.2f"
formatEuro(3.4645)
formatEuro {val rate = 1.32;0.235+0.7123+rate*5.32}
遞歸函數(shù)
調(diào)用自身的函數(shù),可能要檢查某類參數(shù)或外部條件來避免調(diào)用陷入無限循環(huán)
def power(x:Int, n:Int):Long = {
if (n>=1) x * power(x,n-1)
else 1
}
//添加尾遞歸優(yōu)化
@annotation.tailrec
def power(x:Int, n:Int):Long = {
if (n>=1) x * power(x,n-1)
else 1
} //報(bào)錯(cuò)
//因?yàn)檫f歸調(diào)用不是函數(shù)的最后一個(gè)語句
@annotation.tailrec
def power(x:Int, n:Int):Long = {
if (n < 1) 1
else x * power(x,n-1)
}
/*
現(xiàn)在遞歸調(diào)用的確是函數(shù)的最后一項(xiàng),不過實(shí)際上,我們是得到遞歸調(diào)用的結(jié)果,然后乘法,所以乘法才是最后一個(gè)語句。
*/
@annotation.tailrec
def power(x:Int, n:Int, t:Int = 1):Int = {
if (n < 1) t
else power(x,n-1,x*t)
}
嵌套函數(shù)
def max(a:Int, b:Int, c:Int) = {
def max(x:Int, y:Int) = if (x>y) x else y
max(a,max(b,c))
}
//max(Int,Int)嵌套函數(shù)在外部函數(shù)中使用了兩次,局部(嵌套)函數(shù)優(yōu)先于外部函數(shù)
用命名參數(shù)調(diào)用函數(shù)
按名調(diào)用參數(shù)
def greet(prefix:String,name:String) = s"$prefix $name"
val greeting1 = greet("Ms","Brown")
有默認(rèn)值得參數(shù)
def greet(prefix:String="",name:String) = s"$prefix $name" //指定了prefix
val greeting1 = greet(name = "Brown")
Vararg參數(shù)
定義輸入?yún)€(gè)數(shù)可變得函數(shù)。要標(biāo)志一個(gè)參數(shù)匹配一個(gè)或多個(gè)輸入實(shí)參,在函數(shù)定義中需要改參數(shù)類型后面增加一個(gè)星號(hào)(*)
def sum(items:Int*):Int = {
var total = 0
for (i <- items) total += i
total
}
sum(10,20,30)
sum()
參數(shù)組
每個(gè)參數(shù)組用小括號(hào)分隔
def max(x:Int)(y:Int) = if (x>y) x else y
val larger = max(20)(39)
類型參數(shù)
def identity(s:String):String = s
def identity(i:Int):Int = i
//如果對(duì)想要使用得每一個(gè)類型都重新定義函數(shù),就太費(fèi)勁了。
def identity(a:Any):Any = a
val s:String = identity("Hello") //報(bào)錯(cuò)
//使用類型參數(shù)定義
def identity[A](a:A):A = a
val s:String = identity[String]("Hello")
val d:Double = identity[Double](2.717)
//類型推導(dǎo)
val s:String = identity("Hello")
val d:Double = identity(2.717)
//
val s = identity("Hello")
val d = identity(2.717)
方法和操作符
方法是類中定義的一個(gè)函數(shù),這個(gè)類的所有實(shí)例都會(huì)有這個(gè)方法。
val s = "vacation.jpg"
val isJPEG = s.endWith(".jpg")
//s是String的一個(gè)實(shí)例,String類有一個(gè)endWith方法??梢杂妙惷{(diào)用也可以用實(shí)例名
val d = 65.642
d.round
d.floor
d.compare(18.0)//小于、等于、大于d的值,返回1,0,-1
d.+(2.721)
//操作符
d compare 18.0
d + 2.721
生成API文檔的代碼
//為函數(shù)增加Scaladoc首部
/**
*
*
*/
def safeTrim(s:String):String = {
if (s == null) return null
s.trim()
}