第三部分 Scala学习:函数式编程

一、Scala函数的创建

def main(args: Array[String]): Unit = {
    
    
        // 无参 无返回值
        def test():Unit={
    
    
            println("你好!")
        }
        // 调用函数
        test()
        
        // 无参有返回值
        def test0():String={
    
    
            "Hello Scala!"
        }
        println(test0())
        
        //Scala中没有重载概念
        /*
        def test():String={
            "hello Scala"
        }*/

        //有参无返回值
        def test1(name:String):Unit = {
    
    
            printf("%s Scala",name)
        }
        println(test1("Hello"))

        // 有参有返回值
        def test2(name:String):String={
    
    
            name + "Scala!"
        }
        println(test2("Hello"))
        
    }

二、利用Scala自动推断功能来简化函数

    def main(args: Array[String]): Unit = {
    
    

        //TODO 利用Scala自动推断功能来简化函数
        // 1) 如果函数声明时,明确无返回值,那么即使函数中有return也不起作用
        def test():Unit = {
    
    
            return "Hello Scala!"
        }

        // 如果将函数体的最后一行代码进行返回,那么return关键字可以省略
        def test2():String = {
    
    
            // return "hello"
            "Hello"
        }

        println(test2())
        // 如果可以根据函数的最后一行代码推断类型,那么函数返回值类型可以省略
        def test3()={
    
    
            "hello"
        }
        println(test3())

        // 如果函数体中只有一行代码,大括号可以省略
        def test4() = "Hello"
        println(test4())
        println(test4) //即使没加小括号也是调用该函数
        
        //如果函数声明中没有参数列表,小括号也可以省略
        //如果函数小括号省略了,那么访问函数时不能增加小括号
        //声明函数时必须加def
        def test5 = "Hello"
        println(test5)
        // 如果明确函数没有返回值,等号也可以省略
        def test6() {
    
    
            "Hello"
        }
        println(test6()) // 打印出 ()
    }

三、函数的参数

    def main(args: Array[String]): Unit = {
    
    

        //todo 可变参数形式
        def test(s: String*)={
    
    
            println("Hello, " + s)
        }

        test()//Hello, List() 不传参数时参数是一个空的集合

        //Hello, WrappedArray(Java, Scala, Python) 传入多个参数时,参数返回一个包装的数组
        test("Java", "Scala","Python")

        // todo 默认参数
        val name: String = "Hello"
        val age: Int = 20
        def test2(name: String,age: Int = 20): Unit ={
    
    
            println(s"$name, $age")
        }

        test2(name,age) // Hello, 20
        test2(name) // Hello, 20

    }

四、函数式编程

    def main(args: Array[String]): Unit = {
    
    

        // todo 完全面向函数式编程
        // 1.函数可以赋值给变量
        // 2.函数可以作为函数的参数
        // 3.函数可以作为函数的返回值

        def f():Unit = {
    
    
            println("function")
        }

        def f0() = {
    
    
            // 返回值
            // 直接返回函数,由于当函数无参数时,直接写函数名即为调用,
            // 所以要返回无参函数时,必须加特殊符号_
            // 把函数和方法分开来说,即使方法不能被返回,
            // 所以需要先把方法转换成函数来返回
            // 也就是说,将方法转换为函数的方法是在方法名前加_
            f _
        }
        println(f0()) // <function0>
        f0()() // function

        // todo 简化
        /*
        def f2() = {

            def f1(): Unit = {
                println("function")
            }

            f1 _
        }*/
        // todo 带参
        def f2(i: Int) = {
    
    

            def f1(j: Int): Int = {
    
    
                i * j
            }

            f1 _
        }
        println(f2(2)(3)) // 6

        // todo 函数柯里化
        def f3(i: Int)(j: Int):Int = {
    
    
            i*j
        }
        // 可以看到值传一个参数时,返回值是一个函数
        val f33: Int => Int = f3(2)
        println(f33(3)) //6

        // todo 闭包:改变了外部变量的生命周期,把它包含到逻辑的内部形成一个
        //          闭环的操作,称为闭包
        def f2(i: Int) = {
    
    

            def f1(j: Int): Int = {
    
    
                i * j
            }

            f1 _
        }
    }

五、面向对象

1. Scala中的变量必须显示的初始化

object PrintTest {
    
    
    def main(args: Array[String]): Unit = {
    
    

        // 
        val user: User = new User()
        println(user.age)
        user.username = "Hello"
        println(user.username)



    }
}

// 声明类
class User{
    
    

    // 声明属性
    // Scala类中声明的属性必须显示初始化,如果不想自己初始化,可以通过_由系统初始化
    var username : String = _

    var age : Int = _

    def login(): Boolean = {
    
    
        true
    }
}

2. Scala中的包概念

package com.atguigu.bigdata.scala

// Scala 中的包声明方式默认和Java是一致的,但是有其他的使用方式
// 1)在同一个源文件可以多次声明,声明的类在最后声明的那个包中
        // 源码中类所在路径不需要和包路径相同
package test // 当在另一个包中使用Emp类时,导的包是
                // import com.atguigu.bigdata.scala.test.Emp
// 2)Scala中所有语法均可嵌套
// package 可以使用小括号,小括号内声明的类在这个包中,之外声明的类不在这个包中
// 3) Scala 中可以声明父包和子包,父包中的类,子类可以直接访问,不需要引入,其实就是作用域的概念
// 4)Scala package中可以声明类,但是无法声明变量和函数(方法)
// 5) Scala为了弥补包的不足,使用了包对象的概念,其中可以声明属性和方法
package object Test5{
    
     //对象的声明方式
    // 可以声明属性和方法
    var name: String = _
    var age: Int = _
    def login()={
    
    

    }
    class Emp{
    
    

    }
}
package test1 {
    
    
    package test2{
    
    

    }
}

object PrintTest {
    
    
    def main(args: Array[String]): Unit = {
    
    

        //
        val emp: Emp = new Emp()



    }
}

class Emp{
    
    

}

3. Scala中import

import 用于导入类
import 可以在任意的地方使用
import 可以导入一个包里的所有类,采用下划线代替星号
import java.util._
import 导入相同的包中多个类,采用大括号进行包含处理 import java.util.{ArrayList,List,Date}
import 可以采用特殊的方式来隐藏指定的类:{类名=>} import java.util.{Date=>}
import 可以导包,此时使用 import java.util new util.Date()
scala中如果想要从最开始的包中查找类,需要增加绝对路径,使用_root_开头
可以在在导入类的时候给类起别名 import java.util.{HashMap=>JavaHashMap}

4.类的属性

object Scala_Field {
    
    
    def main(args: Array[String]): Unit = {
    
    
        val user: User = new User
        println(user.username)
        user.username = "zhangsan"

       // user.email="lisi" 此时该变量由于是常量,不能重新赋值

        // 由于通过BeanProperty注解,scala中提供了相应的Setter和Getter方法
        user.setAdress("Nanjing")
        user.getAdress()
    }
}

class User {
    
    

    //生命属性
    //scala中给类声明属性,默认为私有的,但是底层提供了Setter和getter方法
    var username: String = _
    //如果属性增加private修饰符,那么属性无法在外部访问,因为底层生成的Setter和Getter方法都是私有的
    private var age: Int = _

    // 如果申明的属性使用val 那么属性是私有的,并且使用的final修饰,底层只提供Setter方法,而且没有Setter方法
    val email: String = ""//此时必须显示的初始化
    // 为了和Java bean规范统一,scala提供了注解,生成Java中对应的set,get方法
    @BeanProperty var address: String = _
}

5.访问权限

Scala中也有四种访问权限
public protected default(package) private

  1. public 是默认的访问权限,没有关键字
  2. protected 访问权限值能子类访问,同包也访问不了
  3. private 私有访问权限,只能当前类访问
  4. 包访问权限需要采用特殊的语法规则:private[包名]
package com.atgugui.bigdata.scalalearning

package A {
    
    

    package P1 {
    
    

        class User2 {
    
    
            val name: String = "zhangsan"
            private val age: Int = 18
            protected val email:String = "[email protected]"
            private [P1] val address:String ="Beijing"
        }

    }

    package P2 {
    
    

        import com.atgugui.bigdata.scalalearning.A.P1.User2
        class Emp extends User2 {
    
    
        //class Emp {
    
    

            val emp: Emp = new Emp //
            println(emp.name)//只能访问这一个权限
            //println(user.address) 当把中括号中的包名改为P2也能访问该属性
            println(emp.email)  //当继承父类是就可以访问父类被protected修饰的父类属性了

        }
    }
}

猜你喜欢

转载自blog.csdn.net/pageniao/article/details/104435430