闭包 Scala学习笔记-面向对象篇

以前一直不知道什么叫闭包,网上找了半天也没明白,只知道闭包的定义:

代码+非局部变量 = 闭包

代码好理解,那什么时非局部变量呢?
首先我们定义一个种树的方法:

def plantATree(treeName:String)={
  var high= 0
  val taller(meter:Int)={
      high += meter
      println("大家好,我是"+treeName+",今年我"+high+"米了")
  }
  taller
}

在这个例子里涉及到了scala中的函数嵌套,我们知道,嵌套中的函数可以访问上层函数的变量,也就是taller这个函数可以访问 high和treeName。
好了,现在解释先这个函数的目的,plantATree,顾名思义,就是要种一棵树,返回一个taller这个函数,taller接受一个int,意思是这棵树长高了。
下面我们开始种树:

val treeOne = plantATree("银杏")
val treeTwo = plantATree("苹果树")

其实现在我们已经产生了两个闭包,为什么呢,我们运行如下代码,我们先让苹果树长高3米

treeTwo(3)

苹果树说:

大家好,我是苹果树,今年我3米了

现在我们再让银杏树长高1米,运行如下代码

treeOne(1)

银杏树说:

大家好,我是银杏,今年我1米了

大家发现,银杏树和苹果树都各自维护了一套非局部变量,因为treeName和high并不是taller的局部变量,而是上层函数的。
这就是所谓的闭包,就是把代码和非局部变量打包起来,各自维护一套。即使上层函数已经运行完毕。

在java面向对象的编程风格里,方法只能相互调用,不能嵌套。大家有没有觉得java中内部类有点强行不让你闭包的意思,因为内部类调用外部类变量必须声明为final。因为java中没有闭包,目的就是为了防止发生变量值得混乱。

题外话:
当然了,java8已经做了翻天覆地的变化,又是lambda,又是闭包,而且还引入了函数式编程,各种新特征打得火热,还增加了类似于scala的管道编程风格的Stream API。

有兴趣的可以看看下面几个链接:
http://kb.cnblogs.com/page/110782/
http://www.cnblogs.com/uptownBoy/articles/1454098.html
http://lovejavaei.iteye.com/blog/401167

你可能感兴趣的:(闭包)