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