1、函数高级应用
主要包含 10 种函数高级应用, 包括 函数传名调用 指定函数参数名调用 可变参数的函数 默认参数值函数 递归函数 高阶函数 内嵌函数 匿名函数 偏应用函数 函数柯里化 |
- 1) 函数传名调用
- 概念说明
- 传值调用:先计算参数表达式的值,再应用到函数内部, 把=>去掉即可,即按原始的方式
- 传名调用:将未计算的参数表达式直接应用到函数内部, 用=>来设置传名调用
- 应用示例-传值
- 概念说明
object TestCallByValue {
def main(args: Array[String]) { delayedCalculator(transmitMe());
}
def transmitMe(): String = { println("我在 transmitMe 方法中!") return "transmitMe 返回值";
}
def delayedCalculator(t: String): Unit = { println("在 delayedCalculator 方法--开始") println("正式调用传过来的函数: " + t) println("在 delayedCalculator 方法--结束")
}
}
应用示例-传名
|
- 2)指定函数参数名调用
|
- 3)可变(不定长)参数的函数
object TestNonFixParas { def main(args: Array[String]) { printAllParasValue("one", "two", "three", "four"); } def printAllParasValue(paras: String*): Unit = { for (temp <- paras) { println(temp); } } |
- 4)默认参数值函数
object TestDefaultParaFunction { def main(args: Array[String]) { println("完全使用默认值的返回值 : " + salaryMoney()); println("部分使用默认值的返回值 : " + salaryMoney(10)); println("部分使用默认值的返回值 : " + salaryMoney(10,10000)); } def salaryMoney(a: Int = 5, unit: Int = 1000): Int = { return a * unit } } |
- 5)递归函数
object TestRecusive { def main(args: Array[String]) { var n=4 println(n+"的阶乘为="+myFactorial(n)) } def myFactorial(n: Int): Int = { if (n <= 1) return 1 else return n * myFactorial(n - 1) } } |
- 6)高阶函数
- 概念说明
- 第一种:将一个函数当做另外一个函数的参数,即参数为函数的函数
- 第二种:返回值是函数的函数,即高阶函数可以产生函数
- 应用示例
- 参数为函数的函数
- 概念说明
object TestHighFunctionByTransmitFunctionPara { def main(args: Array[String]) {
delayedCalculator(transmitMe());
}
def transmitMe(): String = { println("我在 transmitMe 方法中!") return "transmitMe 返回值";
}
def delayedCalculator(t: => String): Unit = { println("在 delayedCalculator 方法--开始") println("正式调用传过来的函数: " + t) println("在 delayedCalculator 方法--结束")
}
}
返回值是函数的函数
object TestHighFunctionByRetFunction { def main(args: Array[String]) { var mySalaryFun=multiplyBy(1000); println(mySalaryFun(10)); } def multiplyBy(salaryUnit:Int)=(x:Int)=>salaryUnit*x } |
- 7)内嵌函数
- 概念介绍
- 函数内定义函数,定义在函数内的函数称之为局部函数, 亦称内嵌函数
- 应用示例
- 概念介绍
object TestEmbedFunction { def main(args: Array[String]) { var msg="HelloWorld"; printMessage(msg); } def printMessage(msg: String): Unit = { def printMessageInner(msg: String): Unit = { println(msg); } printMessageInner(msg); } } |
- 8)匿名函数
- 概念介绍
- 没有函数名称的函数
- 使代码更简洁,用=>来表示,左侧是参数列表,右侧是函数体
- 概念介绍
o 应用示例
-
-
- 匿名用法(使值自增+1 的函数实现)
-
函数定义: var inc = (x:Int) => x+1 |
函数使用: var x = inc(8)+1 |
-
-
- 正常写法(使值自增+1 的函数实现)
-
正常定义: def incFunction(x: Int): Int = { return x + 1; } 函数使用: var x=incFunction(8)+1 |
- 9)偏应用函数
- 概念说明
- 不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数
- 实现方法:绑定函数的一部分参数,非绑定部分用"_"代替,从而形成偏应用函数去使用
- 应用示例
- 传统方法实现(向某人问好)
- 概念说明
import java.util.Date object TestPartialParasFunction { def main(args: Array[String]) { val name="张三" sayHello(name, "上午好") Thread.sleep(1000) sayHello(name, "中午好") Thread.sleep(1000) sayHello(name, "晚上好") } def sayHello(name: String, message: String) = { println(name + "----" + message) } } |
-
-
- 偏应用函数实现(向某人问好)
-
def main(args: Array[String]) { val name="张三" val partialSay=sayHello(name,_:String); partialSay("上午好") Thread.sleep(1000) partialSay("中午好") |
Thread.sleep(1000) partialSay("晚上好") } def sayHello(name: String, message: String) = { println(name + "----" + message) } |
- 10) 函数柯里化
- 概念说明
- 将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。
- 提高了使用方法的灵活性
- 应用举例
- 传统实现 add 方法定义
- 概念说明
def add(x: Int, y: Int) = x + y;
- 传统实现add 方法使用
def main(args: Array[String]) { println(add(3,4)); } def add(x: Int, y: Int) = x + y; |
- 柯里化实现add 方法定义
def add(x:Int)(y:Int) = x + y
- 柯里化实现add 方法使用
object TestCurryingFunction { def main(args: Array[String]) { //对应柯里化形式 1 的使用 var curryingAdd1 = add1(3) //对应柯里化形式 2 的使用 var curryingAdd2 = add2(3)(_) println(curryingAdd1(4)); println(curryingAdd1(4)); } //柯里化形式 1 def add1(x: Int) = (y: Int) => x + y; //柯里化形式 2 def add2(x: Int)(y: Int) = x + y; } |
2、集合 collection
- 概念说明
- 该集合与 Java 中的集合类似,只是 scala 重新实现了自身的集合抽象
- 分为可变集合和不可变集合
- 常用集合列表
序号 | 集合类 | 说明 |
1 | Scala List(列表) | 元素以线性方式存储,集合中可以存放重复对象。 |
2 | Scala Set(集合) | 集合中的对象不按特定的方式排序,并且没有重复对 象。 |
3 | Scala Map(映射) | KV 对存储 |
4 | Scala 元组 | 元组是不同类型的值的集合 |
5 | Scala Option | 表示有可能包含值的容器,也可能不包含值。 |
6 | Scala Iterator 迭代器 | 迭代器不是一个容器,更确切的说是逐一访问容器内元素的方法 |
- 应用示例
- Scala List(列表)
- 概念说明
- 类似于数组,要求所有元素的类型都相同,通过范型来约束
- 列表是不可变集合,一旦定义了就不能改变
- 列表具有递归定义的性质,可以嵌套定义,这是与数组最大的不一样。
- 应用示例
- 概念说明
def main(args: Array[String]) { // 字符串列表 val language: List[String] = List("java", "python", "c++") // 整型列表 val nums: List[Int] = List(1, 2, 3, 4) // 空列表 val empty: List[Nothing] = List() // 二维列表 val dim: List[List[Int]] = List( List(1, 0, 0), List(0, 1, 0), |
List(0, 0, 1)) } |
-
- 用 Nil 和::来构建列表
def main(args: Array[String]) { // 字符串列表 val language= "java" :: ("python" :: ("c++" :: Nil)) // 整型列表 val nums = 1 :: (2 :: (3 :: (4 :: Nil))) // 空列表 val empty = Nil // 二维列表 val dim = (1 :: (0 :: (0 :: Nil))) :: (0 :: (1 :: (0 :: Nil))) :: (0 :: (0 :: (1 :: Nil))) :: Nil |
- 常用操作
- head 返回列表第一个元素
- tail 返回一个列表,包含除了第一元素之外的其他元素
- isEmpty 在列表为空时返回 true
- ::: 运算符或 List.:::() 方法或 List.concat() 方法来连接两个或多个列表
- List.fill() 方法来创建一个指定重复数量的元素列表
- List.tabulate() 方法是通过给定的函数来创建列表。
- List.reverse 用于将列表的顺序反转
- 应用示例
object TestListFunction { def main(args: Array[String]) { val language1 = "java" :: ("python" :: ("c++" :: Nil)) val nums = Nil /** * 基本操作 */ println("基本操作------------ "); println("第一语言是 : " + language1.head) println("除第 1 个语言之外的其它语言是 : " + language1.tail) println("查看列表 site 是否为空 : " + language1.isEmpty) println("查看 nums 是否为空 : " + nums.isEmpty) /** * 列表连接 */ |
println("列表连接------------ ");
val language2 = "c" :: ("php" :: ("go" :: Nil))
// 使用 ::: 运算符
var mainLanguages = language1 ::: language2 println("language1 ::: language2 : " + mainLanguages)
// 使用 List.:::() 方法
mainLanguages = language1.:::(language2) println("language1.:::(language2) : " + mainLanguages)
// 使用 concat 方法
mainLanguages = List.concat(language1, language2) println("List.concat(language1, language2) : " +
mainLanguages)
/**
* fill 填充列表的重复元素
*/
println("List fill------- ");
val bestLanguage = List.fill(3)("php") // 重复 Runoob
3 次
println("bestLanguage : " + bestLanguage)
val num = List.fill(10)("php") // 重复元素 "php", 10 次
println("num : " + num)
/**
* List tabulate 通过给定的函数来创建列表
*/
println("List tabulate------- ");
// 通过给定的函数创建 6 个元素
val squares = List.tabulate(6)(n => n * n) println("一维 : " + squares)
// 创建二维列表
val mul = List.tabulate(4, 5)(_ * _) println("多维 : " + mul)
/**
* List.reverse 用于将列表的顺序反转
*/
println("List.reverse------- ");
println(mainLanguages.reverse);
}
}
- Scala Set(集合)
- 概念说明
-
-
- 没有重复的对象集合,所有的元素都是唯一的
- Set 集合分为可变的和不可变的集合
- 默认使用不可变集合,完整类路径为: scala.collection.immutable.Set
- 若要引用可变集合类型,则类路径为: scala.collection.mutable.Set
- 基础应用示例
- 不可变集合使用
-
def main(args: Array[String]): Unit = { //初始化 set 集合 val set = Set(1, 2, 3, 4, 5, 6) //得到对应的 set 路径 println(set.getClass.getName) //利用 exists 方法,判断集合元素中是否存在%2==0 的元素 println(set.exists(_ % 2 == 0)) //打印当前集合序列println(set) } |
- 可变集合使用
def main(args: Array[String]): Unit = { //初始化 set 集合 val mutableSet = Set(1, 2, 3, 4, 5, 6) //获取可变集合的 set 路径 println(mutableSet.getClass.getName) //添加元素mutableSet.add(4) println("添加元素 4 后="+mutableSet) //删除元素mutableSet.remove(1) println("删除元素 1 后="+mutableSet) mutableSet += 7 println("+7 后"+mutableSet) mutableSet -= 2 println("-2 后"+mutableSet) //将可变 set 转换成不可变 set val another = mutableSet.toSet println(another.getClass.getName) // scala.collection.immutable.Set } |
- 常用操作
-
- head 返回集合第一个元素
- tail 返回一个集合,包含除了第一元素之外的其他元素
- isEmpty 在集合为空时返回 true
- 使用 ++ 运算符或 Set.++() 方法来连接两个集合
- 使用 Set.min 方法来查找集合中的最小元素,使用 Set.max 方法查找集合中的最大元素
- 使用 Set.& 方法或 Set.intersect 方法来查看两个集合的交集元素。实例
- 常见应用示例
def main(args: Array[String]): Unit = {
val languageSet1 = Set("java", "python", "c++") val numSet: Set[Int] = Set()
/**
* 基本操作
*/
println("基本操作------------ ");
println("第一语言是 : " + languageSet1.head) println("除第 1 个语言之外的其它语言是 : " +
languageSet1.tail)
println("查看列表 site 是否为空 : " + languageSet1.isEmpty)
println("查看 nums 是否为空 : " + numSet.isEmpty)
/**
* 集合连接操作
*/
println("集合连接------------ ");
val languageSet2 = Set("c", "php", "go")
// ++ 作为运算符使用
var mainlanguageSet = languageSet1 ++ languageSet2 println("languageSet1 ++ languageSet2 : " +
mainlanguageSet)
// ++ 作为方法使用
mainlanguageSet = languageSet1.++(languageSet2) println("languageSet1.++(languageSet2) : " +
mainlanguageSet)
/**
* 求集合最大、最小元素
*/
println("求集合最大和最小元素------------ ");
println("mainlanguageSet 集合中的最小元素是 : " + mainlanguageSet.min)
println("mainlanguageSet 集合中的最大元素是 : " + mainlanguageSet.max)
/** * 求交集 */ println("求集合的交集------------ ") var secondLanguageSet=Set("shell","perl","java") println("mainlanguageSet.&(secondLanguageSet) : " + mainlanguageSet.&(secondLanguageSet)) println("mainlanguageSet.intersect(secondLanguageSet) : " + mainlanguageSet.intersect(secondLanguageSet)) } |
- Scala Map(映射)
- 概念说明
- 一种可迭代的键值对(key/value)结构,也称为哈希表
- 所有的值都可以通过键来获取,键值是唯一的
- 两种类型,可变与不可变,区别在于可变对象可以修改它,而不可变对象不可以
- 默认使用的不可变 Map,可变的 Map 需要使用 import scala.collection.mutable.Map 类
- 基础示例
- 概念说明
def main(args: Array[String]): Unit = { // 不可变空 Map,键为字符串,值为整型 var personMap: Map[String, String] = Map() // 不可变初始化 val languageMap = Map("java" -> "java 程序设计", "python" -> "python 程序设计", "c++" -> "c++程序设计") //动态向不可变 map 中添加值 personMap += ("001" -> "张三") //languageMap += ("java" -> "已经理新了") //此处会报错println(personMap) println(languageMap) //初始化可变 Map val languageMap2 = scala.collection.mutable.Map("java" -> "java 程序设计", "python" -> "python 程序设计", "c++" -> "c++程序设计") //向可变 Map 中添加值languageMap2.put("python","已经更新了") println(languageMap2) } |
- 关于不可变和可变Map 的总结
- 不可变 Map
-
-
- api 不太丰富
- 如果是 var 修饰,引用可变,支持读写
- 如果是 val 修饰,引用不可变,只能写入一次值,其后只读
- 可变 Map
- api 丰富与 Java 中 Map 基本类似
- 如果是 var 修饰,引用可变,支持读写
- 如果是 val 修饰,引用不可变,支持读写
- 总结
- 可变与不可变,主要是通过 val 和 var 来限定达到意图
- api 丰富程度不一样
-
- 常用操作
- keys:返回 Map 所有的键(key)
- values:返回 Map 所有的值(value)
- isEmpty:在 Map 为空时返回 true
- 使用++运算符或Map.++()方法来连接两个 Map,Map 合并时会移除重复的 key。
- 通过 foreach 循环输出 Map 中的 keys 和 values:
- 使用 Map.contains 方法来查看 Map 中是否存在指定的 Key
- 综合示例
def main(args: Array[String]): Unit = { // 不可变空 Map,键为字符串,值为整型 var personMap: Map[String, String] = Map() // 不可变初始化 val languageMap = Map("java" -> "java 程序设计", "python" -> "python 程序设计", "c++" -> "c++程序设计") /**
*/ println("基础操作-------------- ") println("languageMap 中的键为 : " + languageMap.keys) println("languageMap 中的值为 : " + languageMap.values) println("检测 languageMap 是否为空:" + languageMap.isEmpty) println("检测 personMap 是否为空: " + personMap.isEmpty) /**
*/ println(" map 合并-------------- ") val languageMap2 = Map("C" -> "C 程序设计") |
// ++ 作为运算符 var mainLanguages = languageMap ++ languageMap2 println("languageMap ++ languageMap2 : " + mainLanguages) // ++ 作为方法 mainLanguages = languageMap.++(languageMap2) println("languageMap.++(languageMap2)) : " + mainLanguages) /**
*/ println("map 的 keys 和 values 输出----------------- ") mainLanguages.keys.foreach { i => print("Key = " + i) println(" Value = " + mainLanguages(i)) } /**
*/ println("查看 Map 中是否存在指定的 Key-------- ") if (mainLanguages.contains("java")) { println("java 键存在,对应的值为 :" + mainLanguages("java")) } else { println("java 键不存在") } if (mainLanguages.contains("c#")) { println("java 键存在,对应的值为 :" + mainLanguages("c#")) } else { println("c#键不存在") } } |
- Scala 元组
- 概念说明
- 与列表相似,元组是不可变的
- 与列表不同的是,元组可以包含不同类型的元素
- 元组是通过"()"来定义的
- 应用示例
- 概念说明
def main(args: Array[String]): Unit = { //直接定义元组 var personInfo = ("s0001", "张三", 21, "河北科技大学", 1.80) |
//通过 TupleN 来定义,N 可以是 1 至 22 个可选的元组个数 var pessonInfoTuple5 = new Tuple5("s0001", "张三", 21, "河北科技大学", 1.80); /**
*/ println("元组访问-------------- "); println("学号=" + personInfo._1); println("姓名=" + personInfo._2); println("年龄=" + personInfo._3); println("学校=" + personInfo._4); println("身高=" + personInfo._5); /** * 元组遍历 */ println("元组遍历-------------- "); personInfo.productIterator.foreach { i => println("元素值 = " + i) } /** * 元组转换成字符串 */ println("元组转换成字符串---------------- "); println(personInfo.toString()) } |
- Scala Option[T]
- 概念说明
- 表示有可能包含值的容器,也可能不包含值。主要用来表示一个值是可选的
- Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。
- 常用方法
- getOrElse() 方法来获取元组中存在的元素或者使用其默认的值
- isEmpty() 方法来检测元组中的元素是否为 None
- 应用示例
- 概念说明
def main(args: Array[String]): Unit = { //定义一个 map 对象 val mainLanguagesMap = Map("java" -> "java 程序设计", "python" -> "python 程序设计") //通过指定键值,获取可能的 value,其返回值是一个Option[T],代表有可能会存在该键值对应的 value,也有可能不存在 |
var javaDesc: Option[String] = mainLanguagesMap.get("java"); var phpDesc: Option[String] = mainLanguagesMap.get("php"); //打印拿到的结果println("mainLanguagesMap.get(\"java\") : " + javaDesc) println("mainLanguagesMap.get(\"php\") : " + phpDesc) //判断结果是否有值,即是否为 None println("javaDesc.isEmpty: " + javaDesc.isEmpty) println("phpDesc.isEmpty: " + phpDesc.isEmpty) //对拿到的结果做 getOrElse 操作,即如果不存在该 key,则取方法的默认值 println("mainLanguagesMap.get(\"java\") : " + javaDesc.getOrElse("没有拿到 java 的描述信息")) println("mainLanguagesMap.get(\"php\") : " + phpDesc.getOrElse("没有拿到 php 的描述信息")) } |
- Scala Iterator(迭代器)
- 概念说明
- 不是一个集合,它是一种用于访问集合的方法。
- 基本操作是 hasNext 和 next
- 常用方法或属性
- it.hasNext() 用于检测集合中是否还有元素。
- it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态
- max:取得迭代器对应集合的最大值
- min:取得迭代器对应集合的最小值
- size/length:取得迭代器对应集合的长度
- 应用示例
- 概念说明
def main(args: Array[String]): Unit = { val it1 = Iterator("java", "python", "c++") val it2 = Iterator("java", "python", "c++") val it3 = Iterator("java", "python", "c++") val it4 = Iterator("java", "python", "c++") val it5 = Iterator("java", "python", "c++") /** * 迭代器遍历集合 */ |
println("遍历集合-------------- "); while (it1.hasNext) { println(it1.next()) } /**
*/ println("求迭代器集合的最大值-------------- "); println(it2.max) /**
*/ println("求迭代器集合的最小值-------------- "); println(it3.min) /**
*/ println("迭代器求集合的长度-------------- "); println(it4.size) println(it5.length) } |
3、类和对象
- 概念说明
- 类和对象通用说明
- 类是对象的抽象,而对象是类的具体实例。
- 类是抽象的,不占用内存,而对象是具体的,占用存储空间。
- 类是用于创建对象的模板,它定义包括在特定类型的对象中的方法和变量。
- scala 类和对象介绍
- 一个 Scala 源文件中可以有多个类。
- 类访问修饰符默认均是 public 的,并不需要声明
- 通过 new 来实例化类,生成相应的对象
- 类本身是不能作为程序主入口的,必须通过定义 Object 对象,该对象的 main 方法作为程序的主入口
- 类和对象通用说明
- 应用示例
-
- 基础示例
/** * 主构造方法传参,共三个参数,分别为姓名、性别、年龄 */ class Person(oneName: String, oneGender: String, oneAge: Int) { //将构造方法传入的局部变量,传递成类的成员变量,方便后续在外部使用使用var name: String = oneName var gender: String = oneGender var age: Int = oneAge //定义成员方法 def makeMoney(method: String) { println("makeMoney method=" + method); } } /** * 定义一个对象作为程序的运行主类,其 main 方法作为程序运行的主入口 */ object TestPerson { def main(args: Array[String]): Unit = { //通过 new 实例化 Person 类的一个对象 person var person = new Person("张一", "male", 20) //通过对象.属性的方式,获取对象的属性值println("person.name=" + person.name) println("person.gender=" + person.gender) println("person.age=" + person.age) //通过对象.方法名(参数)的方式,调用方法 person.makeMoney("coding") } } |
- 类继承
- 概念说明
- Scala 继承一个基类跟 Java 很相似,但有若干不同之处。
- 重写一个非抽象方法必须使用 override 修饰符
- 只有主构造函数才可以往基类的构造函数里写参数
- 在子类中重写超类的抽象方法时,你不需要使用 override 关键字
- 应用示例
- 概念说明
/** * 主构造方法传参,共三个参数,分别为姓名、性别、年龄 */ class Person(oneName: String, oneGender: String, oneAge: Int) { //将构造方法传入的局部变量,传递成类的成员变量,方便后续在外部使用使用 |
var name: String = oneName var gender: String = oneGender var age: Int = oneAge //定义成员方法 def makeMoney(method: String) { println("makeMoney method=" + method); } } /** * Student 类继承 Person 类,将相关属性直接传递给父类构造方法 */ class Student(oneStdNo: String, oneName: String, oneGender: String, oneAge: Int) extends Person(oneName, oneGender, oneAge) { //将新增加构造方法的参数值赋给的成员属性,方便后续在外部使用 var stdNo = oneStdNo; //重写父类的非抽象成员方法,必须填加 override 关键字 override def makeMoney(method: String) { println("我是个学生,我的学号是" + this.stdNo + ",makeMoney method=" + method); } } /** * 定义一个对象作为程序的运行主类,其 main 方法作为程序运行的主入口 */ object TestPerson { def main(args: Array[String]): Unit = { //通过 new 实例化 Person 类的一个对象 person var person = new Student("s0001", "张一", "male", 20) //通过对象.属性的方式,获取对象的属性值println("person.stdno=" + person.stdNo) println("person.name=" + person.name) println("person.gender=" + person.gender) println("person.age=" + person.age) //通过对象.方法名(参数)的方式,调用方法person.makeMoney("coding") } } |
- 单例模式
- 概念说明
- static 在 scala 中是没有的,不符合纯面向对象的模型。
- scala 中使用 object 关键字来解决单例模式问题。object 与类的区别是 object 不能够带参数。
- 概念说明
-
- 简单版单例模式
object ChineseSingleton { var skinColor = "Yellow" var country = "中国人" } object TestSingleton { def main(args: Array[String]): Unit = { println(ChineseSingleton.skinColor) println(ChineseSingleton.country) ChineseSingleton.skinColor = "黄色"; println(ChineseSingleton.skinColor) } } |
- scala 经典版单例模式
- 概念说明
- 伴生对象:除了定义的类之外,还要定义一个同名的object 对象,当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:companion object
- 伴生类:该伴生对象对应的类,即为伴生类 companion class
- 必须在同一个源文件里定义类和它的伴生对象
- 类和它的伴生对象可以互相访问其私有成员
- 应用示例
- 概念说明
/** * 定义伴生类 */ class TaskManager private (oneName: String) { //将构造方法传入的局部变量,传递成类的成员变量,方便后续在外部使用使用var name: String = oneName //定义成员方法 def getName(): String = { return name; } } /**
*/ object TaskManager { var taskManager = new TaskManager("windows 任务管理器"); def getSingletonInstance(): TaskManager = { return taskManager |
} } /** * 测试单例模式 */ object TestSingleton { def main(args: Array[String]): Unit = { var singleton = TaskManager.getSingletonInstance(); println(singleton.getName()); } } |
4、特质 trait
- 概念说明
- 相当于 Java 的接口和抽象类的二合一,即可以当接口使用,也可以像抽象类去定义实际的方法和抽象方法去使用。
- 特征是支持多继承的,解决了 scala 单继承的问题,间接达到scala 多继承的效果。
- 用关键字 trait 来定义特征
- 应用示例
/** * 定义核心计算特征 */ trait CalcuteCoreTrait { def add(a: Int, b: Int): Int = a + b def minus(a: Int, b: Int): Int = a - b def factorial(n: Int): Int } class TLCalculator(oneName: String) extends CalcuteCoreTrait { var name = oneName def factorial(n: Int): Int = { if (n <= 1) { return 1 } else { return n * factorial(n - 1) } } } |
object TestTrait { def main(args: Array[String]): Unit = { var tl:CalcuteCoreTrait=new TLCalculator("晨光计算器") var a=3 var b=4 println("a+b="+tl.add(a, b)) println("a-b="+tl.minus(a, b)) println("b!="+tl.factorial(b)) } } |