关于Scala和面向对象的函数式编程
2019独角兽企业重金招聘Python工程师标准>>>
这是一个很好的Scala的入门介绍,原文:http://my.oschina.net/mup/blog/363436
定义
Scala语言是一种面向对象语言,同时又结合了命令式(imperative)和函数式(functional)编程风格。官网描述:Object-Oriented Meets Functional(面向对象遇到函数式编程)。
安装
下载地址http://www.scala-lang.org/download/
当前版本2.11.4
设置环境变量
?
1
2
|
export SCALA _ HOME = /home/mupeng/Hadoop/scala- 2.11 . 4
export PATH = $SCALA _ HOME/bin : $PATH
|
如果是修改的profile,执行source /etc/profile,使环境变量立即生效。
检测安装是否成功命令 scala -version,如果出现以下内容,证明安装成功。
?
1
2
|
scala -version
Scala code runner version 2.11 . 4 -- Copyright 2002 - 2013 , LAMP/EPFL
|
Scala解释器
直接输入scala,就进入scala解释器
?
1
2
3
4
|
scala
Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35).
Type in expressions to have them evaluated.
Type :help for more information.
|
先来两个例子,熟悉以下scala解释器
?
1
2
|
scala> 1+2
res0: Int = 3
|
结果被命名为res0,Int指结果类型,3指计算结果
?
1
2
|
scala> println( "hello scala" )
hello scala
|
输出hello scala
变量
Scala中的变量有两种var和val(val类似于Java中final,值不可改变)
scala> var hello = "hello world"
hello: String = hello world
scala可以根据赋值内容推算出变量类型。Scala中的数据类型都是对象。
函数
Scala是面向对象语言同时也是函数式编程语言,因此函数在Scala语言中的地位同对象、变量一样。使用scala函数注意一下几点:
1) 函数参数写在类型之前,中间用逗号隔开;
?
1
2
3
|
def helloScala = {
println( "Hello Scala!" )
}
|
2) 函数都有返回结果,无需使用return,函数内最后一个表达式作为返回结果返回。helloScala函数的返回类型为Unit,表示该函数不返回任何有意义的值(相当于Java中的void)。
3) 函数参数可以给定默认值。
?
1
2
3
|
def hello(name : String = "Scala" ) : String = {
return "Hello : " + name
}
|
4) 函数的参数都是val类型,执行过程中不能被改变。(函数式编程的特点,只计算结果,不改变参数)
5) 定义方法还有如下方式
def add = (x : Int, y : Int) => x + y
打印结果print(add(1, 2));
def add2(x : Int)(y : Int) = x + y
打印结果print(add2(1)(2))
循环
在了解循环之前,我们先要知道Scala不支持i++和++i,需要使用i+=1来实现加一。
while循环
?
1
2
3
4
5
|
var i = 0
while (i < args.length) {
println (args(i))
i+ = 1
}
|
for循环
?
1
2
|
for (arg <-args)
println(arg)
|
for参数里面同样支持if判断,比如输出1——10中的偶数
?
1
2
|
for (i <- 1 to 10 if i % 2 == 0 )
println(i)
|
foreach
?
1
|
args.foreach(arg = > println(arg))
|
因为参数只有一个,表达式也只有一个,可以简写为
?
1
|
args.foreach(println)
|
Array与List
创建数组有两种方式
?
1
2
3
4
|
val greetStrings = new Array[String]( 3 )
greetStrings( 0 ) = "Hello"
greetStrings( 1 ) = ", "
greetStrings( 2 ) = "world!\n"
|
或者
?
1
|
val numNames = Array( "zero" , "one" , "two" )
|
注意与Java不同的是:数组的第零个元素是greetStrings(0),不是greetStrings[0]。
Array长度不可变,但是它的值可变。
List长度与值都不可变。
?
1
2
3
4
|
val list 1 = List( 1 , 2 )
val list 2 = List( 3 , 4 )
val list 3 = list 1 ::: list 2 //list3结果为(1,2,3,4)
val list 4 = 0 :: list 3 //list4结果为(0,1,2,3,4)
|
这里有两个操作 ::: 连接两个List
:: 右操作符,将一个新元素放到List的最前端。
类与对象
1. 定义类
?
1
2
3
4
5
6
|
class Person {
var email = "abc123@126.com" // 变量,var声明会生成getter和setter方法
var name : String = _ // 变量, _起到占位符的作用
val age = 10 ; // 常变量,val声明只会生成getter
private val gender = "male" //只能在类内部使用
}
|
缺省访问级别是public,一个源文件中可以有多个class,都是public的。
2. 主构造器
?
1
2
3
|
class Student( var name : String, val number : String) {
println( "主构造器!" )
}
|
1)主构造器直接跟在类名后面,主构造器的参数最后会被编译成字段。
2)主构造器执行的时候,会执行类中所有的语句。
3)如果主构造器参数声明时候不加val或者var,就相当于private
3. 从构造器
?
1
2
3
4
5
6
7
8
|
class Student( var name : String, val number : String) {
println( "主构造器!" )
var gender : String = _
def this (name : String, number : String, gender : String) {
this (name, number)
this .gender = gender
}
}
|
1)从构造器定义在类内部,方法名为this
2)从构造器必须先调用已经存在的构造器
4. 继承:继承而来的字段不需要加var或者val
?
1
2
3
|
class UniversityStudent(name : String, number : String, val major : String) extends Student(name, number) {
......
}
|
注意:重写父类的字段或方法要在前面加上override关键字
5. 抽象类(abstract class)与特质(trait)
1)抽象方法不需要加关键字,只有声明,没有具体实现。
2)可以声明抽象字段,也就是没有初始值。
3)子类重写父类的抽象方法或者抽象字段,不需要加override
trait特质可以理解为可以有具体实现方法的接口,类可以通过with关键字混入(mix-in)特质,同时它的对象也可以混入特质。
Scala程序的执行入口是提供main方法的独立单例对象。同样也可以给一个单例对象混入App特质,去继承App特质中的main方法.
6. apply方法
1)对象的apply方法
?
1
2
3
4
5
6
7
8
9
10
|
class ApplyTest {
println( "Test" )
}
object ApplyTest {
def apply() = new ApplyTest
}
// 调用方法
val a = ApplyTest() // 类名+括号,调用对象的apply方法
|
上面例子中一个调用apply方法,生成一个新的对象。(绝大多数apply方法都是这样去用)
apply方法就是Scala提供的一个语法糖,对象的apply方法在scala里面非常常用
例如:
?
1
2
3
4
5
|
val arr = Array( 1 , 2 , 3 )
实际调用的是
val arr = Array.apply( 1 , 2 , 3 )
|
以下是Array对象的apply方法源码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
object Array extends FallbackArrayBuilding {
...
/** Creates an array of `Int` objects */
// Subject to a compiler optimization in Cleanup, see above.
def apply(x : Int, xs : Int*) : Array[Int] = {
val array = new Array[Int](xs.length + 1 )
array( 0 ) = x
var i = 1
for (x <- xs.iterator) { array(i) = x; i + = 1 }
array
}
...
}
|
2)类的apply方法
?
1
2
3
4
5
6
7
8
9
|
class ApplyTest {
def apply() {
println( "APPLY Method" )
}
println( "Test" )
}
val a = new ApplyTest
a() // 对象名+括号,调用类的apply方法
|
7.单例
用object替换class,其它的跟定义类类似。
当单例对象与类共享同一个名字时,该对象称作类的伴生对象。
与Java对比
如果用作服务器端开发,Scala的简洁、灵活性是Java无法比拟的;如果是企业级应用开发、Web开发,Java的强大是Scala无法匹敌 的。我们不用一种语言的优势去抨击另一种语言的短板,所以不要说Java与Scala孰优孰劣,更不要说谁将要取代谁,二者本来就是互补关系。
总结
scala语言的知识点有太多太多,在一篇博客中不可能做到一一列举。本文只是列举了常用的的几点,希望对正在学习scala的人有所帮助。
转载于:https://my.oschina.net/u/2306127/blog/366988
关于Scala和面向对象的函数式编程相关推荐
- 《Java8实战》笔记(15):面向对象和函数式编程的混合-Java 8和Scala的比较
面向对象和函数式编程的混合:Java 8和Scala的比较 Scala是一种混合了面向对象和函数式编程的语言.它常常被看作Java的一种替代语言,程序员们希望在运行于JVM上的静态类型语言中使用函数式 ...
- Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程
内容目录: Reactor实现架构对比 面向对象的Reactor方案设计 函数式编程的Reactor设计 示例对比 两者的时序图对比 结论 Reactor事件驱动的两种设计实现:面向对象 VS 函数式 ...
- 【2023】Kotlin教程 第二篇 面向对象与函数式编程 第15章 数据容器——数组和集合 15.2 集合概述
[2023]Kotlin教程 文章目录 [2023]Kotlin教程 第二篇 面向对象与函数式编程 第15章 数据容器--数组和集合 15.2 集合概述 第二篇 面向对象与函数式编程 第15章 数据容 ...
- 图灵奖得主Alan Kay谈面向对象和函数式编程
Alan Kay授权<程序员>整理翻译并本文.译/王江平 原文链接 https://news.ycombinator.com/item?id=11808551 本文为<程序员> ...
- 测试和恢复性的争论:面向对象vs.函数式编程
Michael Feathers最近的博文在博客社区引发了一场异常激烈的论战.Feathers发表言论说一些面向对象编程语言的内嵌特性有助于测试的进行,并且使用面向对象编程语言编写的代码更容易恢复. ...
- javascript中的面向对象_面向对象和函数式编程的本质区别
编程的本质 当写过许许多多程序后,接触了那么多编程模式.设计模式.框架.语言.算法.数据结构以后,就会发现编程的本质万变不离其宗就是,操纵一坨数据.当然操纵的方式有许多,存储的方式也五花八门,但是本质 ...
- Scala - 快速学习08 - 函数式编程:高阶函数
函数式编程的崛起 函数式编程中的"值不可变性"避免了对公共的可变状态进行同步访问控制的复杂问题,能够较好满足分布式并行编程的需求,适应大数据时代的到来. 函数是第一等公民 可以作为 ...
- javascript消除字符串两边空格的两种方式,面向对象和函数式编程。python oop在调用时候的优点...
主要是javascript中消除字符串空格,比较两种方式的不同 //面向对象,消除字符串两边空格 String.prototype.trim = function() { return this.re ...
- 告别相杀!面向对象和函数式编程共存
作为结构化编程的一种,函数式编程正受到越来越多的重视.而作为常用的一种程序开发方法,面向对象编程为程序设计带来了更强的灵活性和可维护性.那么两者相较而言,究竟有着什么样的区别?应用场景又有何不同? 作 ...
- Java 设计模式最佳实践:一、从面向对象到函数式编程
原文:Design Patterns and Best Practices in Java 协议:CC BY-NC-SA 4.0 贡献者:飞龙 本文来自[ApacheCN Java 译文集],采用译后 ...
最新文章
- 21条高效时间管理法则
- Linux - Ubuntu
- 菲律宾政府网站被黑!
- 脚本升级_手把手教你升级到Database 19c(3)| 终章教程
- 福建省考计算机专业,2020福建省考,这些报考专业问题你清楚吗?
- PHP中将首字母大写的函数,在PHP中,使用()函数来将单词首字母转换为大写。
- shell 批量生成随机文件
- Android异常处理——try、catch、finally、throw、throws
- winform 可拖动的自定义Label控件
- MATLAB图像滤波去噪分析及其应用
- Android apk签名详解——AS签名、获取签名信息、系统签名、命令行签名
- CSAPP第八章家庭作业参考答案
- SQL语句实现模糊查询
- win10电脑网速慢怎么解决
- 前端开发和后端开发究竟有什么区别?详细介绍
- lisp语言cond和if套用_方案 – if和cond之间的区别?
- php后端上传文件,php实现文件上传方法_后端开发
- 小学数学计算机整合课后反思,2020小学数学教研组工作总结_小学数学教学反思心得五篇...
- 【UE4】unlua往c++传动态委托参数的方式
- 201621123031 《Java程序设计》第4周学习总结
热门文章
- wpf 引用的图片文件打包后找不到_PyQT5打包:用PyInstaller遇到的坑
- php html5 应用缓存,HTML5 应用程序缓存
- 统计自然语言处理梳理一:分词、命名实体识别、词性标注
- 【Interfacenavigation】隐藏导航栏(52)
- 阿里云ECS云服务器通过SAP HANA认证 海量数据处理技术助力企业数字化转型
- iphone:点击背景隐藏键盘
- 思科又发紧急安全通告 IOS集群管理协议漏洞和Struts2漏洞 有影响产品列表及应对措施了...
- 2.原子变量 CAS算法
- 如何在java对象里访问Spring中已加载的property内容
- 用css实现了一个精致的纵向导航菜单