函数式编程
基础函数编程
函数定义
package learn03
object demo01 {
def main(args: Array[String]): Unit = {
//无参、无返回值
def fun1(): Unit = {
println("函数体")
}
fun1()
//无参、有返回值
def fun2(): String = {
"xwk"
}
println(fun2())
//有参、无返回值
def fun3(name: String): Unit = {
println(name)
}
fun3("xwk")
//有参、有返回值
def fun4(name: String): String = {
"Hello " + name
}
println(fun4("xwk"))
//多参、无返回值
def fun5(hello: String, name: String): Unit = {
println(hello + " " + name)
}
fun5("Hello", "xwk")
//多参、有返回值
def fun6(hello: String, name: String): String = {
hello + " " + name
}
println(fun6("Hello", "xwk"))
}
}
函数参数
package learn03
object demo02 {
def main(args: Array[String]): Unit = {
//可变参数
def fun7(names: String*): Unit = {
println(names)
}
fun7()
fun7("xwk")
fun7("xwk", "zxy")
//可变参数不能放置在参数列表的前面,一般放置在参数列表的最后
//def fun77(names:String*,name:String):Unit={},这是错误的写法
def fun77(name: String, names: String*): Unit = {
println(name)
println(names)
}
//参数默认值
def fun8(name: String, password: String = "000000"): Unit = {
println(name + "," + password)
}
fun8("xwk", "123456")
fun8("xwk")
//带名参数
def fun9(password: String = "000000", name: String): Unit = {
println(name + "," + password)
}
fun9("123456", "xwk")
fun9(name = "xwk")
}
}
函数至简原则
package learn03
object demo03 {
def main(args: Array[String]): Unit = {
//省略return关键字
def fun1(): String = {
return "省略return关键字前"
}
def fun11(): String = {
"省略return关键字"
}
println(fun1())
println(fun11())
//省略花括号
def fun2(): String = "省略花括号"
println(fun2())
//省略返回值类型
def fun3() = "省略返回值类型"
println(fun3())
//省略参数列表
def fun4 = "省略参数列表"
println(fun4) //正确
//fun4()错误
//省略等号
//如果函数体中有明确的return语句,那么返回值类型不能省略
def fun5_1(): String = {
return "省略等号1"
}
println(fun5_1())
//如果函数体返回值类型明确为Unit, 那么函数体中即使有return关键字也不起作用
def fun5_2(): Unit = {
return "省略等号2"
}
println(fun5_2())
//如果函数体返回值类型声明为Unit, 但是又想省略,那么此时就必须连同等号一起省略
def fun5_3(){
return "省略等号3"
}
println(fun5_3())
//省略名称和关键字
() => {
println("省略名称和关键字")
}
}
}
高阶函数编程
所谓的高阶函数,其实就是将函数当成一个类型来使用,而不是当成特定的语法结构。
package learn03
object demo04 {
def main(args: Array[String]): Unit = {
//函数作为值
def fun1(): String = {
"xwk"
}
val a = fun1
val b = fun1 _
val c: () => Unit = fun1
println(a)
println(b)
//函数作为参数
def fun2(i: Int): Int = {
i * 2
}
def fun22(f: Int => Int): Int = {
f(10)
}
println(fun22(fun2))
//函数作为返回值
def fun3(i: Int): Int = {
i * 2
}
def fun33() = {
fun3 _
}
println(fun33()(10))
//匿名函数
def fun4(f: Int => Int): Int = {
f(10)
}
println(fun4((x: Int) => {
x * 20
}))
println(fun4((x) => {
x * 20
}))
println(fun4((x) => x * 20))
println(fun4(x => x * 20))
println(fun4(_ * 20))
//控制抽象
def fun7(op: => Unit) = {
op
}
fun7 {
println("xx")
}
//闭包
def fun5() = {
val i = 20
def fun55() = {
i * 2
}
fun55 _
}
fun5()()
//函数柯里化
def fun6(i: Int)(j: Int) = {
i * j
}
//递归函数
def fun8(j: Int): Int = {
if (j <= 1) {
1
} else {
j * fun8(j - 1)
}
}
println(fun8(5))
//惰性函数
def fun9(): String = {
println("function......")
"xwk"
}
lazy val x = fun9()
println("........")
println(x)
}
}
面向对象编程
基础面向对象编程
包
package关键字可以嵌套声明使用
package learn03
package p1 {
package p2 {
package p3 {
object demo01 {
def main(args: Array[String]): Unit = {
println("test...")
}
}
}
}
}
同一个源码文件中子包可以直接访问父包中的内容,而无需import
Scala中package也可以看作对象,并声明属性和函数
导入
scala中基本的import导入语法和java完全一致
java中import导入的语法比较单一,scala对此进行扩展
package learn03
object demo05{
def main(args: Array[String]): Unit = {
//scala中的import语法可以在任意位置使用
import java.util.ArrayList
new ArrayList()
//scala中可以导包,而不是岛类
import java.util
new util.ArrayList()
//scala可以在同一行中导入相同包中的多个类,简化代码
import java.util.{
List,ArrayList}
//屏蔽某个包中的类
import java.util._
import java.sql.{
Date=>_,Array=>_,_}
//给类起别名
import java.util.{
ArrayList=>AList}
new AList()
//可以使用类的绝对路径而不是相对路径
import _root_.java.util.ArrayList
//默认情况下,scala中会导入如下包和对象
import java.lang._
import scala._
import scala.Predef._
}
}
类
class User{
//类的主体内容
}
//对象 : new 类名(参数列表)
new User()
scala中的一个源文件中可以声明多个公共类
属性
扫描二维码关注公众号,回复: 14796267 查看本文章
package learn03
object demo06 {
def main(args: Array[String]): Unit = {
class User {
var name : String = _ // 类属性其实就是类变量
var age : Int = _ // 下划线表示类的属性默认初始化
}
}
}
访问权限
private : 私有访问权限
private[包名]: 包访问权限
protected : 受保护权限,不能同包
: 公共访问权限(默认)
方法
Scala中的类的方法其实就是函数,所以声明方式完全一样,但是必须通过使用对象进行调用
package learn03
object demo07 {
def main(args: Array[String]): Unit = {
val user=new User
user.login("xwk","000000")
}
}
class User{
def login(name:String,password:String):Boolean={
false
}
}
对象
val | var 对象名 [:类型] = new 类型()
var user : User = new User()
构造方法
package learn03
class User() {
// 主构造函数
var username : String = _
def this( name:String ) {
// 辅助构造函数,使用this关键字声明
this() // 辅助构造函数应该直接或间接调用主构造函数
username = name
}
def this( name:String, password:String ) {
this(name) // 构造器调用其他另外的构造器,要求被调用构造器必须提前声明
}
}
高阶面向对象编程
继承
package learn03
class Person {
}
package learn03
class User extends Person{
}
抽象
Scala将一个不完整的类称之为抽象类
abstract class Person{
}
Scala中如果一个方法只有声明而没有实现,那么是抽象方法,因为它不完整。
abstract class Person{
def test():Unit
}
Scala中如果一个属性只有声明没有初始化,那么是抽象属性,因为它不完整。
abstract class Person{
var name:String
}
子类如果继承抽象类,必须实现抽象方法或补全抽象属性,否则也必须声明为抽象的,因为依然不完整。
class User extends Person{
var name:String="xwk"
}
abstract class Person{
var name:String
}
单例对象
所谓的单例对象,就是在程序运行过程中,指定类的对象只能创建一个,而不能创建多个。这样的对象可以由特殊的设计方式获得,也可以由语言本身设计得到,比如object伴生对象
Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,该对象为单例对象。若单例对象名与类名一致,则称该单例对象这个类的伴生对象,这个类的所有“静态”内容都可以放置在它的伴生对象中声明,然后通过伴生对象名称直接调用
如果类名和伴生对象名称保持一致,那么这个类称之为伴生类。Scala编译器可以通过伴生对象的apply方法创建伴生类对象。apply方法可以重载,并传递参数,且可由Scala编译器自动识别。所以在使用时,其实是可以省略的。
class User {
// 伴生类
}
object User {
// 伴生对象
def apply() = new User() // 构造伴生类对象
}
...
val user1 = new User()// 通过构造方法创建对象
Val user2 = User.apply() // 通过伴生对象的apply方法构造伴生类对象
val user3 = User() // scala编译器省略apply方法,自动完成调用