- 面向对象编程
解决问题,分解对象,行为,属性,然后通过对象的关系以及行为的调用来解决问题。
对象:用户;
行为:登录、连接jdbc、读取数据库
属性:用户名、密码
Scala语言是一个完全面向对象编程语言。万物皆对象 - 函数式编程
解决问题时,将问题分解成一个一个的步骤,将每个步骤进行封装(函数),通过调用这些封装好的步骤,解决问题。
例如:请求->用户名、密码->连接jdbc->读取数据库
Scala语言是一个完全函数式编程语言。万物皆函数 - 在Scala中函数式编程和面向对象编程融合在一起了。
方法基本语法
语法:
说明:
- def : 关键字,表示声明方法
- add:方法名,根据业务进行取名
- 参数名称在前 : 参数类型在后,多个参数用 , 分割
- 返回类型:若无返回类型 可定义为 Unit 或 无需定义
- 函数体:用于编写的业务逻辑的语句块
与java方法的区别:
- scala 可以将函数定义到任意位置,甚至在一个函数内定义一个函数。
def main(args: Array[String]): Unit = {
def sayHello(){
print("hello")
}
sayHello // hello
}
- java 只能将方法定义在类中,不能定义在另一个方法中
方法的定义:
- 函数1:无参,无返回值
def sayHello(){
print("hello")
}
- 函数2:无产,有返回值
def main(args: Array[String]): Unit = {
println(sayHello) // hello
}
def sayHello():String={
"hello"
}
- 函数3:有参,无返回值
def main(args: Array[String]): Unit = {
sayHello("张三")
}
def sayHello(name:String){
println(s"你好,$name 童鞋") // 你好,张三 童鞋
}
- 函数4:有参,有返回值
def main(args: Array[String]): Unit = {
println(sum(10,20)) // 30
}
def sum(x:Int,y:Int):Int={
x+y
}
- 函数5:多参,无返回值
def main(args: Array[String]): Unit = {
sum(10,20) // 30
}
def sum(x:Int,y:Int){
println(x+y) //30
}
- 在scala中函数可以不用加
return
用来标识返回值,在scala中会以最后一个参数或表达式的结果作为返回值。
方法参数
可变参数
无论是 scala 还是 java 他们都支持 可变参数
java :使用 ...
来表示
scala:使用 *
来表示
案例:
def main(args: Array[String]): Unit = {
info("坤坤","唱","跳","Rap","篮球")
}
def info(name:String,hobby:String*):Unit={
println(s"我叫$name,我的爱好有${hobby.toList}") // 我叫坤坤,我的爱好有List(唱, 跳, Rap, 篮球)
}
可变参数底层实现都是一个数组或集合,所以直接遍历可变参。
def info(name:String,hobby:String*):Unit={
for (h <- hobby){
println(h)
}
}
唱
跳
Rap
篮球
使用 可变参数需要注意:
- 被定义成可变参数的参数,需要放在参数列表最后。
- 一个方法中只能有一个可变参数。
- 可变参数不能与带名参数一起使用(后面会讲)
带参默认值
在程序开发中,往往有这样的需求,当某些值为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'
定义的参数,就是表示给参数一个默认值。
常见错误写法:
-
sex='M' :Char
:我有时候也不会搞错,直到运行报错才反应过来。 -
sex='M'
:这种形式的写法也是错误的,必须指定类型。
带名参数
以上面的案例说明;第一个参数为姓名
,第二个参数为年龄
,第三个参数为性别
,一般情况下函数调用参数,就按照函数定义时的参数顺序一个个传递。但是我们也可以通过指定函数参数名,并且不需要按照顺序向函数传递参。
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 会使用函数体的最后一行代码作为返回值
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):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
}
- 如果函数明确声明 unit,那么即使函数体中使用 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.如果参数无参,但是声明了参数列表,那么调用时,小括号,可以不加。
def sayHello{print("hello")}
sayHello
- 如果函数没有参数列表,那么小括号可以省略,调用时小括号必须省略
定义函数:def sayHello{print("hello")}
掉用函数:必须省略小括号 sayHello
- 如果不关心名称,只关心逻辑处理,那么函数名称(def)可以省略。这种声明方式叫做 匿名函数(lambda 表达式)。
()=>{print("hello")}
总结:虽然很多简化原则,但是不用去记,多敲就完了(我也记不住,没事的时候,回顾一下笔记,知道个大概就行了。
函数的定义
语法
val 函数名 =(参数名:类型,...) => {函数体}
// 计算两个数的和
val sum=(x:Int,y:Int)=>{
x+y
}
println(sum(2,3)) // 5
- 并不需要写返回值,函数的返回值就是块表达式最终返回代码结果。
- 调用函数和调用方法是一样的。
函数的简化
- return 可以省略,scala 会使用函数体的最后一行代码作为返回值
val sum=(x:Int,y:Int)=>{
x+y
}
- 如果函数体只有一行代码,可以省略花括号
// 计算两个数的和
val sum=(x:Int,y:Int)=> x+y
println(sum(2,3)) // 5
- 返回值类型如果能够推断出来,那么可以省略(:和返回值类型一起省略)
// 计算两个数的和
val sum=(x:Int,y:Int)=> x+y
println(sum(2,3)) // 5
- 如果有 return,则不能省略返回值类型,必须指定。
函数中无法指定返回值,至少我试了好几次没成功
- 如果函数明确声明 unit,那么即使函数体中使用 return 关键字也不起作用
上面的都不行,这个也自然没用了
- scala 如果期望时无返回值类型,可以省略等号
没有等号,哈哈哈
- 如果参数无参,但是声明了参数列表,那么调用时,小括号,可以不加。
val sayHello=()=>{
println("hello")
}
不行,无法调用;函数就是一个对象,sayHello 这是这个函数的引用,并不是调用。
sayHello
打印一下该引用,输入的其实就内存地址。
println(sayHello) // Demo02$$$Lambda$1/764977973@1fbc7afb
正确写法
sayHello()
函数与方法的区别
官方函数的定义
- 函数的定义:
(x: Int) => x + 1
- 方法的定义:
def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3
函数与方法概念
- 方法就是函数,函数就是一个对象
scala> val sum=(x:Int,y:Int)=>{x+y}
sum: (Int, Int) => Int = $$Lambda$1032/841090268@778a1250
$$Lambda$1032/841090268@778a1250 就是 sum 函数的内存地址。
方法存在方法区,对象存在堆内存中。
- 函数调用必须带上
()
,否则无法调用 - 方法写在类中,方法是可以被重载,函数无法被重载
方法:
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={
对于函数,无论是在类中,还在方法中,都是不行的,因为函数需要定义变量名;变量名不能重复
。
val sum=(x:Int,y:Int)
val sum=(x:Int,y:Int,z:Int)
- 方法转函数:
方法名 _
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
}
函数的另一种写法
FunctionNum
:Num
表示0-22个数字。最多只有23种
Function0:表示0个参数
Function1:表示1个参数
Function10:表示10个参数
Function22:表示22个参数
依旧拿 sum
为例
val sum=(x:Int,y:Int)=>{
x+y
}
它有两个参数;所以使用 Function2
:
val sum2=new Function2[Int,Int,Int] {
override def apply(v1: Int, v2: Int) = v1+v2
}
Function2[Int,Int,Int] :
第一个Int:表示第一个参数的类型
第二个Int:表示第二个参数的类型
第三个Int:表示返回值的类型
需要重写它的 apply
方法;在内部做运行
override def apply(v1: Int, v2: Int)
如果代码很多,是可以指定{}
将代码包起来
override def apply(v1: Int, v2: Int) = {
v1+v2
}
对比一下原来的形式
// 计算两个数的和
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目前处于学习阶段,以上内容都是我学习的总结,至于内容质量,仁者见仁,不好的大家提出来,相互进步,能帮助你的,我也很高兴。