前面我们已经学习了特质类似接口,其可以被继承,同时如果需要继承多个特质的话,则需要使用extends…with…进行继承。其类似java中的接口和抽象方法的结合体,但又比java中的其要强大,因为其可以定义抽象字段和普通字段、抽象方法和普通方法。而在java中接口中可以定义常量,不能定义变量。同时特质还可以继承class类,而在java中接口通常是用来实现的。
Object继承trait
//object单例对象继承特质objectOopDemo{ //定义一个特质,添加方法,monkey会playtraitMonkey{ defplay(msg:String) } //定义特质traitEat{ defeat(msg:String) } //定义单例对象ProgramMonkey继承上面的两个特质,并重写两个方法objectProgramMonkeyextendsMonkeywithEat{ overridedefplay(msg:String): Unit=println("monkey会玩很多游戏:"+msg) overridedefeat(msg:String): Unit=println("monkey同样会吃:"+msg ) } defmain(args: Array[String]): Unit= { //调用programMonkey单例对象中重写的两个方法ProgramMonkey.play("玩球球") ProgramMonkey.eat("吃香蕉") } }
trait中带成员变量
objectOopDemo{ //定义一个特质MonkeytraitMonkey{ //具体字段varname=""//抽象字段varage:Int//具体方法defeat() =println("吃香蕉") //抽象方法defplay():Unit } //定义一个类,继承Monkey特质,重写方法和字段classProgramMonkeyextendsMonkey{ //重写抽象字段overridevarage:Int=28//重写父特质中的抽象方法overridedefplay(): Unit=println(s"${name}的年龄是${age},喜欢玩球") } //main方法defmain(args: Array[String]): Unit= { //创建程序猿对象valpm=newProgramMonkey//进行赋值pm.name="程序猿"pm.age=28//进行输出println(pm.name+"-------"+pm.age) //调用方法pm.eat() pm.play() } }
trait继承class
在scala中,trait可以继承class类,特质会将class中的成员都继承下来
//class 类A{//成员变量//成员方法 //}//trait B extends A{//特质B继承A类//}
objectOopDemo{ //定义类messageclassMessage{ defprintMsg()=println("我是一个类") } //创建特质继承message类traittraitMessageextendsMessage//定义类继承特质classMyMessageextendstraitMessagedefmain(args: Array[String]): Unit= { //创建MyMessage类的对象,调用printMsg方法valmyMessage=newMyMessagemyMessage.printMsg() } }
样例类
在Scala中,样例类是一种特殊类,一般用于保存数据(类似java中的pojo类)
caseclass样例类名([val/var] 成员变量名1:类型1,成员变量名2:类型2,成员变量名3:类型3)
如果不写,则变量的默认修饰符是val,如果要实现某个成员变量值可以被修改,则需手动添加var来修饰此变量.
objectOopDemo{ //创建一个Monkey类caseclassMonkey(name:String="程序猿",varage:Int=28) {} //创建main方法defmain(args: Array[String]): Unit= { //创建对象valm=newMonkeyprintln(m) m.age=27println(m) } }
当我们定义一个样例类后,编译器会自动帮助我们生成一些方法, 常用的如下:
-apply()方法-toString()方法-equals()方法-hashCode()方法-copy()方法-unapply()方法
样例对象
在Scala中, **用case修饰的单例对象就叫: 样例对象, 而且它没有主构造器 **, 它主要用在两个地方:
当枚举值使用作为没有任何参数的消息传递
case object 样例对象名
objectOopDemo{ //定义特质sex traitSex//定义枚举值male、femalecaseobjectMaleextendsSexcaseobjectFemaleextendsSex//定义Monkey(name:String,sex:Sex)caseobjectMonkey(name:String,sex:Sex) {} //定义main函数defmain(args: Array[String]): Unit= { //创建Monkey类valm=Monkey("程序猿",Male) println(m) } }
数组
数组就是用来存储多个同类型元素的容器, 每个元素都有编号(也叫: 下标, 脚标, 索引), 且编号都是从0开始数的.
Scala中, 有两种数组,一种是定长数组,另一种是变长数组.
//val/var 变量名 = new Array[元素类型](数组长度)//val/var 变量名 = Array(元素1,元素2,元素3,...)
objectOopDemo{ defmain(args: Array[String]): Unit= { vararr1=newArray[Int](10) arr1(0) =10println(arr1(0)) vararr2=Array("java","scala","spark") println(arr2.length) } }
变长数组
//导入ArrayBuffer类importscala.collection.mutable.ArrayBuffer//创建变长数组//val/var 变量名 = ArrayBuffer[元素类型]()//val/var 变量名 = ArrayBuffer(元素1,元素2,元素3,...)
objectOopDemo{ defmain(args: Array[String]): Unit= { valarr1=newArrayBuffer[Int]() println("arr1:"+arr1) //创建变长数组vararr2=ArrayBuffer("java","kafka","flink") println("arr2: "+arr2) } }
进行数组的增删改
使用+=添加单个元素使用-=删除单个元素使用++=追加一个数组到变长数组中使用--=移除变长数组中的指定多个元素比如:arr++=Array("hive", "spark")
遍历数组
objectOopDemo{ defmain(args: Array[String]): Unit= { valarr=Array(1,2,3,4,5) //进行遍历for(i<-toarr.lengt-1)println(arr(i)) //遍历方式二for(i<-untilarr.length)println(arr(i)) //遍历方式三for(i<-arr)print(i) } }
数组常用算法
sum() 方法: 求和max() 方法: 求最大值min() 方法: 求最小值sorted() 方法: 排序, 返回一个新的数组. reverse() 方法: 反转, 返回一个新的数组. 如:valarr2=arr.sorted
元组
元组一般用来存储多个不同类型的值。例如同时存储姓名,年龄,性别,出生年月这些数据, 就要用到元组来存储
了。并且元组的长度和元素都是不可变的。
val/var元组= (元素1, 元素2, 元素3....) val/var元组=元素1->元素2
objectOopDemo{ defmain(args: Array[String]): Unit= { valtuple1= ("程序员",28) valtuple2="程序猿"->27//进行输出println(tuple1) println(tuple2) } }
遍历元组
在Scala中, 可以通过元组名 ._编号的形式来访问元组中的元素,_1表示访问第一个元素,依次类推. 也可以通过元组名 .productIterator的方式, 来获取该元组的迭代器, 从而实现遍历元组.
objectOopDemo{ defmain(args: Array[String]): Unit= { valtuple1= ("程序员",28) valtuple2="程序猿"->27//进行迭代println(s"名称: ${tuple1._1},年龄: ${tuple1._2}") valit=tuple2.productIteratorfor(i<-it)println(i) } }
列表
列表(List)是Scala中最重要的, 也是最常用的一种数据结构。它存储的数据, 特点是: 有序, 可重复.
在Scala中,列表分为两种, 即: 不可变列表和可变列表.
//val/var 变量名 = List(元素1,元素2,元素3,...)//val /var 变量名 = Nil//val /var 变量名 = 元素1 :: 元素2 :: Nil
objectOopDemo{ defmain(args: Array[String]): Unit= { vallist1=List(1,2,3,4) vallist2=Nilvallist3=-2:: -1 :: Nil//进行输出println(s"list1: ${list1}") println(s"list2: ${list2}") println(s"list3: ${list3}") } }
列表的常用操作
在scala的列表中,还可以实现扁平化
objectOopDemo{ defmain(args: Array[String]): Unit= { //1. 定义一个列表, 该列表有三个元素, 分别为:List(1,2)、List(3)、List(4,5)vallist1=List(List(1,2), List(3), List(4, 5)) //2. 使用flatten将这个列表转换为List(1,2,3,4,5)vallist2=list1.flatten//3. 打印结果println(list2) } }
同时由于set和map和java中的类似,这里就不展示出来了,同时有一点差别在于函数式编程api上,不需要写stream进行操作,而是直接调用函数式方式,同时操作比java更方便。