Scala学习三-面向对象

2020-10-26 15:42:09 浏览数 (1)

前面我们已经学习了特质类似接口,其可以被继承,同时如果需要继承多个特质的话,则需要使用extends…with…进行继承。其类似java中的接口和抽象方法的结合体,但又比java中的其要强大,因为其可以定义抽象字段和普通字段、抽象方法和普通方法。而在java中接口中可以定义常量,不能定义变量。同时特质还可以继承class类,而在java中接口通常是用来实现的。

Object继承trait

代码语言:javascript复制
//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中带成员变量

代码语言:javascript复制
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中的成员都继承下来

代码语言:javascript复制
//class 类A{
   //成员变量
   //成员方法  
//}

//trait B extends A{
    //特质B继承A类
//}
代码语言:javascript复制
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类)

代码语言:javascript复制
case class 样例类名([val/var] 成员变量名1:类型1,成员变量名2:类型2,成员变量名3:类型3)

如果不写,则变量的默认修饰符是val,如果要实现某个成员变量值可以被修改,则需手动添加var来修饰此变量.

代码语言:javascript复制
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)
    }
}

当我们定义一个样例类后,编译器会自动帮助我们生成一些方法, 常用的如下:

代码语言:javascript复制
- apply()方法
- toString()方法
- equals()方法
- hashCode()方法
- copy()方法
- unapply()方法

样例对象

在Scala中, **用case修饰的单例对象就叫: 样例对象, 而且它没有主构造器 **, 它主要用在两个地方:

代码语言:javascript复制
当枚举值使用
作为没有任何参数的消息传递
代码语言:javascript复制
case object 样例对象名
代码语言:javascript复制
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中, 有两种数组,一种是定长数组,另一种是变长数组.

代码语言:javascript复制
//val/var 变量名 = new Array[元素类型](数组长度)
//val/var 变量名 = Array(元素1,元素2,元素3,...)
代码语言:javascript复制
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)
   } 
}
变长数组
代码语言:javascript复制
//导入ArrayBuffer类
import scala.collection.mutable.ArrayBuffer
//创建变长数组
//val/var 变量名 = ArrayBuffer[元素类型]()
//val/var 变量名 = ArrayBuffer(元素1,元素2,元素3,...)
代码语言:javascript复制
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)
   }
}
进行数组的增删改
代码语言:javascript复制
使用  = 添加单个元素
使用 - = 删除单个元素
使用   = 追加一个数组到变长数组中
使用 -- = 移除变长数组中的指定多个元素
比如:
 arr   = Array("hive", "spark")
遍历数组
代码语言:javascript复制
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)  
  }
}
数组常用算法
代码语言:javascript复制
sum() 方法: 求和
max() 方法: 求最大值
min() 方法: 求最小值
sorted() 方法: 排序, 返回一个新的数组.
reverse() 方法: 反转, 返回一个新的数组.
如:val arr2 = arr.sorted

元组

元组一般用来存储多个不同类型的值。例如同时存储姓名,年龄,性别,出生年月这些数据, 就要用到元组来存储 了。并且元组的长度和元素都是不可变的。

代码语言:javascript复制
val /var 元组 = (元素1, 元素2, 元素3....)
val /var 元组 = 元素1->元素2
代码语言:javascript复制
object OopDemo{
  def main(args: Array[String]): Unit = {
    val tuple1 = ("程序员",28)
    val tuple2 = "程序猿"->27
    //进行输出
      println(tuple1)
      println(tuple2)
  }
}
遍历元组
代码语言:javascript复制
在Scala中, 可以通过 元组名 ._编号 的形式来访问元组中的元素,_1表示访问第一个元素,依次类推.
也可以通过 元组名 .productIterator 的方式, 来获取该元组的迭代器, 从而实现遍历元组.
代码语言:javascript复制
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中,列表分为两种, 即: 不可变列表和可变列表.

代码语言:javascript复制
//val/var 变量名 = List(元素1,元素2,元素3,...)
//val /var 变量名 = Nil
//val /var 变量名 = 元素1 :: 元素2 :: Nil
代码语言:javascript复制
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的列表中,还可以实现扁平化

代码语言:javascript复制
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更方便。

0 人点赞