Scala:(四) 方法、函数、Trait

scala中既有函数也有方法,在大多数情况下,不用理会其区别也可正常使用。但有时候还是要区分其异同。
Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。

有些翻译上函数(function)与方法(method)是没有区别的。在写这篇博客的过程中,也参考了一些资料,但大都不能令我满意。所以,知道即可,不要过于追究这劳什子,scala是一门语言,语言自然以使用为第一要务。

方法

Scala中的方法跟Java的方法一样,方法是组成类的一部分。方法有名字、类型签名,有时方法上还有注解,以及方法的功能实现代码(字节码)
我们来定义看一个最经典的方法

函数

再来定义一个函数

其主要区别为:

在函数式编程语言中,函数是“头等公民”,它可以像任何其他数据类型一样被传递和操作
函数定义语法 用def来定义
可以定义传入的参数,要指定传入参数的类型
方法可以写返回值的类型也可以不写,会自动推断,有时候不能省略,必须写,比如在递归函数中或者函数的返回值是函数类型的时候。
scala中函数有返回值时,可以写return,也可以不写return,会把函数中最后一行当做结果返回。当写return时,必须要写函数的返回值。
如果返回值可以一行搞定,可以将{}省略不写
传递给方法的参数可以在方法中使用,并且scala规定方法的传过来的参数为val的,不是var的。
如果去掉方法体前面的等号,那么这个方法返回类型必定是Unit的。这种说法无论方法体里面什么逻辑都成立,scala可以把任意类型转换为Unit.假设,里面的逻辑最后返回了一个string,那么这个返回值会被转换成Unit,并且值会被丢弃。
函数也可作为参数传递到方法里

方法也可转为函数

方法及函数的调用

基本使用与java也类似。同样可以点出来,各种操作符也是可以使用的。
Scala中的+ - * / %等操作符的作用与Java一样,位操作符 & | ^ >> <<也一样。只是有一点特别的:这些操作符实际上是方法。

a + b
是如下方法调用的简写:
a.+(b)
a 方法 b可以写成 a.方法(b)

递归函数

注:递归函数的返回值是必须写的

    /**
     * 递归函数 
     * 5的阶乘
     */
    def fun2(num :Int) :Int= {
      if(num == 1)
        num
      else 
        num * fun2(num-1)  //将函数也作为返回值,直到 num==1
    }
    print(fun2(5))

参数默认值及可变形参

scala与java类似,参数同样可以有默认值,且参数个数也可以是不定的

默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。
如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称。

def fun3(a :Int = 10,b:Int) = {
      println(a+b)
    }
    fun3(b=2)

对于参数不定的,参数之间要用逗号隔开

def fun4(elements :Int*)={
      var sum = 0;
      for(elem <- elements){
        sum += elem
      }
      sum
    }
    println(fun4(1,2,3,4))

Trait

Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现
这里的trait字面意思是特质或者特征,这个词翻译成特征比较合适。它的意义和java,c#中接口很类似。但是trait支持部分实现,也就是说可以在scala的trait中可以实现部分方法。
一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait。
继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。
trait中不可以传参数

trait Read {
  val readType = "Read"
  val gender = "m"
  def read(name:String){
	println(name+" is reading")
  }
}

trait Listen {
  val listenType = "Listen"
  val gender = "m"
  def listen(name:String){
	println(name + " is listenning")
  }
}

class Person() extends Read with Listen{
  override val gender = "f"
}

object test {
  def main(args: Array[String]): Unit = {
    val person = new Person()
    person.read("zhangsan")
    person.listen("lisi")
    println(person.listenType)
    println(person.readType)
    println(person.gender)
    
  }
}

一下引用菜鸟教程的部分内容,原文摘录:

/* 文件名:Test.scala
 * author:菜鸟教程
 * url:www.runoob.com
 */
trait Equal {
  def isEqual(x: Any): Boolean
  def isNotEqual(x: Any): Boolean = !isEqual(x)
}

class Point(xc: Int, yc: Int) extends Equal {
  var x: Int = xc
  var y: Int = yc
  def isEqual(obj: Any) =
    obj.isInstanceOf[Point] &&
    obj.asInstanceOf[Point].x == x
}

object Test {
   def main(args: Array[String]) {
      val p1 = new Point(2, 3)
      val p2 = new Point(2, 4)
      val p3 = new Point(3, 3)

      println(p1.isNotEqual(p2))
      println(p1.isNotEqual(p3))
      println(p1.isNotEqual(2))
   }
}

执行结果为:

false
true
true
posted @ 2020-07-20 22:10  手心里的宇宙  阅读(356)  评论(0编辑  收藏  举报