Scala----主构造 辅助构造 单例对象 apply 继承和实现特质 case calss和case object 模式匹配 OptionSomeNone

主构造器

package cn.doit.com.day03.demo2

//跟在类名的后面,跟类交织在一起,叫主造器  主构造会执行类定义中的所有语句
// 用val和var修饰的构造器参数,会成为这个类的成员变量 默认val修饰 会成为类的成员变量
class Student(val name:String , var age:Int) {
  val i = 100

  //代码块
  {
    try {
      println("hi ketty")
    } catch {
      case e: Exception =>   //可以进行try catch
    } finally {}
  }

  def m():Unit={
    println("hello world")
  }

  var j:Int = _  //给指定的类型的变量赋予默认值

  Student.sayHi()
}

object Student {
  private def sayHi(): Unit ={
    println("hi tom")
  }

  def main(args: Array[String]): Unit = {

  }
}

 

辅助构造器

package cn.doit.com.day03.demo3
//在主构造器中传递的参数可以用val var修饰
class Boy(val name: String , val age: Int) {

  var sal: Double = _  //对应类型变量的的默认初始值
  var gender:String = _

  /*
      定义辅助构造器,辅助构造器一定要用def this,辅助构造器一定要调用
      主构造器或其他的辅助构造器
      辅助构造器的方法中的参数不用加var val修饰
      构造器方法一定是this
                     */
  def this(name:String, age:Int, sal:Double){
    this(name ,age)
    this.sal = sal
  }

  def this(name:String ,age:Int ,sal:Double ,gender:String){
    //调用了辅助构造器 相当于间接调用了主构造
    this(name,age,sal)
    this.gender = gender
  }
}

//不用 var val修饰只是形参
class Boy2(name: String , age: Int){

}

//name weight子类可以继承 private private[this]继承不了 height只是个形参
class Boy3(val name:String , private var age:Int , private[this] val weight:Double , height:Double = 165.0){

}

object Boy {
  def main(args: Array[String]): Unit = {

    val b = new Boy("tom", 18, 12000.0)
    println(b.sal)
  }
}

单例对象   synchronzied同步锁

package cn.doit.com.day03.demo4
/*
    synchronized锁 为保证线程安全
 */
object SynchronizedDemo {
  def main(args: Array[String]): Unit = {

    var m: Int = 10
    test(10)
    test2(20)
    println(m)

    //为了保证线程安全,使用同步synchronized锁
    def test(i: Int): Int = synchronized{
      m = i + m
      //赋值之后重新返回成员变量
      m
    }

    def test2(i: Int): Int ={
      println("hello girl")
      synchronized{
        m = i + m
        m
      }
    }
  }
}
package cn.doit.com.day03.demo4
/*
  单例对象
 */
object ObjDemo  {

    println("hello")
    println("world")

    def abc(): Unit ={
      println("ketty")
    }

    println("jerry")

    abc()
}



object ObjTest {
  def main(args: Array[String]): Unit = {

    val obj = ObjDemo  //初始化静态对象的方式一
    println(obj)

    //单例对象,初始化两次只会执行一次,地址值相同
    val obj2 = ObjDemo
    println(obj2)

    //会执行两次,静态代码块类加载的时候执行一次 ,现在调用它又执行一次
    ObjDemo.abc()
  }
}

apply方法

package cn.doit.com.day03.demo4
/*
  通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数一,...参数二)时,apply方法会被调用
  不仅仅可以在object中定义,class中也可以定义
 */
object ApplyDemo {

  def apply(): Unit = {
    println("no args apply")
  }

  def apply(i: Int , j: Int): Unit = {
    println("two int args apply")
  }

  /*
     方法名相同 参数列表不同
        方法的重载 根据调用时传入的参数区分是哪一个方法
   */
  def apply(i:Int , j:Double): Unit = {
    println("one int one Double args apply")
  }

  def main(args: Array[String]): Unit = {

//    ApplyDemo.apply(1 , 2.0)

    //.apply可以省略掉
    ApplyDemo(1 , 2.5)

    //可以 .apply 证明他是object
    val arr = Array.apply(1,2,3,4,5,6)
    val lst = List(1,2,3,4,5,6)

    val demo = new ApplyClassDemo
    //demo.apply()
    //省略apply
    demo()
  }
}
package cn.doit.com.day03.demo4

class ApplyClassDemo {

  def apply(): Unit={
    println("hello world")
  }
}

App

package cn.doit.com.day03.demo4
/*
    App特质 可以不写main方法也可以运行
    实际是通过反射调用了main方法
 */
object AppDemo extends App {

  println("hello")
  println("tom")
}

继承和实现特质

抽象类父类

package cn.doit.com.day03.demo05
//抽象类 父类
abstract class Animal {
  var name:String
  var age: Int
  def run(): Unit

  //已经实现了的方法
  def breach(): Unit ={
  println("呼吸氧气")
  }
}

子类继承父类 实现特质

package cn.doit.com.day03.demo05
//子类继承父类  with实现接口,可以实现多个接口 中间不需要,
class Monkey extends Animal with Flyable with Fightable {

  //重写抽象 (未实现的方法) 可以加override,也可以不加
  override def run(): Unit = {
    println("蹦蹦跳跳的跑")
  }

  //重写已经实现了的方法 必须加上override关键字
  override def breach(): Unit = {
    println("呼吸新鲜的空气")
  }

  //重写特质中的方法
  override def fly(): Unit = {
    println("坐筋斗云飞")
  }

  //重写了特质中以实现的方法
  override def fight(): Unit = {
    println("金箍棒打你")
  }

  override var name: String = _
  override var age: Int = _
}

object Monkey {
  def main(args: Array[String]): Unit = {

    val monkey = new Monkey
    monkey.breach()
    monkey.fight()
  }
}

特质

package cn.doit.com.day03.demo05
//特质 就是java8的接口
trait Flyable {

  def fly(): Unit
}

特质

package cn.doit.com.day03.demo05

trait Fightable {

  //已经实现了的方法
  def fight(): Unit ={
    println("打你")
  }
}

子类

package cn.doit.com.day03.demo05

//类不论是继承还是实现接口 第一次一定使用extends关键字,之后都是使用with关键字
class Pig extends Flyable with Fightable {

  //重写fly的方法
  override def fly(): Unit = {
    println("飞猪")
  }

  //重写fight的方法
  override def fight(): Unit = {
    println("用九齿钉耙搂你")
  }
}

object Pig {
  def main(args: Array[String]): Unit = {

    val pig = new Pig
    pig.fly()
    pig.fight()
  }
}

动态混入特质

package cn.doit.com.day03.demo05

class Dog {

}

object Dog {
  def main(args: Array[String]): Unit = {

    //动态混入特质  只有特质可以在new的时候实现特质
    val dog = new Dog with Fightable with Flyable {

      //在大括号中重写fight方法
      override def fly(): Unit = {
        println("哮天犬")
      }

      override def fight(): Unit ={
        println("咬你")
      }
    }
    dog.fly()
    dog.fight()
  }
}

多态 父类引用指向子类对象

package cn.doit.com.day03.demo05
//多态  父类引用指向子类对象
object DuoTaiDemo {
  def main(args: Array[String]): Unit = {

    val monkey: Animal = new Monkey
    //重写后的方法
    monkey.run()
    monkey.breach()
  }
}

case class 和 case object

package cn.doit.com.day03.cs

import java.io.{FileOutputStream, ObjectOutputStream}
import scala.beans.BeanProperty

//case可以用来模式匹配和封装案例
//也是一个特殊的class 可以创建多个实例,每个实例封装自己的数据
//可以用于模式匹配
//可以new 也可以不new 内部实现了apply方法
//默认实现序列化接口
//默认重写了toString方法
//case中的主构造器中的变量不加val var  默认就是val的 如果想重新赋值,要加上var
case class CStudent(
                    @BeanProperty  //get set方法   可以指定@beanGetter  @beanSetter
                    name:String ,  //默认val修饰 val可以省略
                    var age:Int
                   ) {
  //重写了toString方法  变量前面加$ , s必须要写
  override def toString: String = s"String: $name , Int $age"
}

object CaseClassDemo {
  def main(args: Array[String]): Unit = {

    val cs = CStudent.apply("zss", 18)
    println(cs.name)
    println(cs.age)


    val oos = new ObjectOutputStream(new FileOutputStream("D:\\a.txt"))
    oos.writeObject(new User)
    oos.flush()
    oos.close()
  }
}
package cn.doit.com.day03.cs

import scala.beans.BeanProperty

//写出到磁盘需要实现序列化接口
class User extends Serializable {

  println("user constructor")

  @BeanProperty
  val name: String = "tom"
  @BeanProperty
  val age: Int = 10
}

模式匹配

package cn.doit.com.day04

import scala.util.Random

object CaseDemo01 extends App{

  val arr = Array("YoshizawaAkiho","YuiHatano","AoiSola")
  //生成随机数
  val name = arr(Random.nextInt(arr.length))
  println(name)
  name match {
    case "YoshizawaAkiho" => {
      println("吉泽***老师")
    }
    case "YuiHatano" => println("波多***老师")
      //通配" _ "
    case _ => println("这不是通往幼儿园的车,我要下车")
  }
}
package cn.doit.com.day04

import scala.util.Random

object CaseDemo02 extends App{
  //if else方法
  //val v = if(x >= 5) 1 else if(x < 2) 2.0 else "hello"
  //创建一个数组传不同类型的参数
  val arr: Array[Any] = Array("hello" , 1 , 2.0 , CaseDemo02)
  //数组生成随机数
  val v =arr(Random.nextInt(4))
  //val v: Any = 2.0
  println(v)

  // n match case => 固定格式
  v match {
      //int类型的值执行x
    case x: Int => {
      println("Int" + x)
    }
      //double类型的值且 y>= 3 执行y
    case y: Double if(y >= 3) => println("Double" + y)
      //string类型的值执行z
    case z: String => println("String" + z)
      //上面条件都不满足执行 _ 通配
    case _ => throw new Exception("not match exception")
  }
}
package cn.doit.com.day04

object CaseDemo03 {
  def main(args: Array[String]): Unit = {

    //匹配数组
    val arr = Array(1,3,5,6)
    arr match {
        //数组首位为1且长度为3 执行
      case Array(1,x,y) => println(x + "" + y)
        //数组中只有0 执行
      case Array(0) => println("only 0")
        //数组中首位为0 _*代表可变参数  执行
      case Array(0,_*) => println("0 ...")
        //上述都不满足 执行
      case _ => println("something else")
    }

    //匹配集合
    val lst = List(0,1,2)
    lst match {
        // 0 :: Nil 把0放进空的list集合中lst(0)  :: 也可以写成 +:  Nil代表空的List集合
      case 0 :: Nil => println("only 0")
        // 把 x,y放进空的list集合中 lst(x,y)
      case x :: y :: Nil => println(s"x: $x , y: $y")
        /*
            list :+ 6   生成一个新的list,6在最后一位 并不是追加 原来的list依然存在
            6 +: list   生成一个新的list,6在首位 也不是追加 原来的list依然存在
            list1 ++ list2   两个list合并 list1和list2依然存在
            list1 :: list2   list1作为一个元素放进list中 List(List(1,2,3),4,5,6)
         */
      //把0放进去掉首位后的集合,代表首位为0
      //head为首位 tail代表去掉首位以外的 返回的是集合  tails返回的是迭代器
      case 0 :: tail => println("0 ...")
        //上述都不满足 执行
      case _ => println("something else")
    }

    //匹配元组
    val tup = (5,3,2)
    tup match {
        //首位为2且长度为3 执行元组中的三个元素
      case (2,x,y) => println(s"2, $x, $y")
        //最后一个元素为5,且长度为3 执行中间数z的值
      case (_,z,5) => println(z)
        //上述都不满足 执行
      case _ => println("else")
    }
  }
}
package cn.doit.com.day04

object WordCount {

  def main(args: Array[String]): Unit = {

    val lines = Array("hadoop,flink,spark,hadoop,Hive","hadoop,Flink,spark,Hadoop,spark")

    val grouped = lines.flatMap(_.split(",")).groupBy(a => a.toLowerCase)
    //元组中的元素特别多,容易混乱,使用模式匹配 match如果省略就要使用大括号
    val a = grouped.map{
      case (word , arr) => {
        (word , arr.length)
      }
    }
    println(a)
  }
}

样例类  样例对象  case class Demo   /   case object Demo

package cn.doit.com.day04

import scala.util.Random
/*
    样例类 样例对象: 专门用来模式匹配的,样例类可以创建多个实例,样例object是单例的
    样例类创建实例后可以封装数据,样例object不能保存数据
    样例类不需要new
 */
//样例类
case class SubmitTask(id:String , name:String)

case class HeartBeat(time:Long)

//样例对象 , 单例的 在一个JVM进程中只有一个实例
case  object CheckTimeOutTask

object CaseDemo04 extends App{

  val arr:Array[Product] = Array(CheckTimeOutTask , new HeartBeat(12333) , HeartBeat(5555) , SubmitTask("0001","task-0001"))

  val r = arr(Random.nextInt(arr.length))
  println(r)

  r match {
    case SubmitTask(id , name) => {
      println(s"$id , $name")
    }
    case HeartBeat(time) => {
      println(time)
    }
    case CheckTimeOutTask => {
      println("check")
    }
  }
}

偏函数(PartialFunction) 专门用来做模式匹配的

package cn.doit.com.day04

object PartialFuncDemo {

  //PartialFunction类型的方法就叫做偏函数
  // String代表输入的类型  Int代表返回的类型
  def func1: PartialFunction[String , Int] ={
    case "one" => 1
    case "two" => 2
    case _ => -1
  }

  //不用偏函数也可以实现
  def func2(num: String): Int = num match {
    case "one" => 1
    case "two" => 2
    case _ => -1
  }

  def main(args: Array[String]) {
    println(func1("two"))
    println(func2("two"))
  }
}

OptionSomeNone

package cn.doit.com.day03.demo06

object OptionDemo {
  def main(args: Array[String]): Unit = {

   val mp = Map("a" -> 1 , "b" -> 2)
    //传入的参数如果找不到就会报错
//   val r:Int = mp.apply("c")
//    println(r)

    //option代表这个参数有可能有,有可能没有
//    val op:Option[Int] = mp.get("b")
//
//    val r =op match {
//        //如果有这个值返回这个值
//      case Some(x) => x
//        //如果没有这个值返回0
//      case None => 0
//    }

    //有b返回b,没有返回-1 底层就是optionSomeNode   推荐使用
    val r = mp.getOrElse("b",-1)
    println(r)
  }
}

模式匹配小案列

package cn.doit.com.day03.demo06

object WordCount {

  def main(args: Array[String]): Unit = {

    val lines = Array("hadoop,flink,spark,hadoop,Hive", "hadoop,Flink,spark,Hadoop,spark")

    val grouped = lines.flatMap(_.split(",")).groupBy(a => a.toLowerCase)
    //元组中的元素特别多,容易混乱,使用模式匹配 match如果省略就要使用大括号
    val a = grouped.map {
      case (word, arr) => {
        (word, arr.length)
      }
    }
    println(a)
  }
}

 

你可能感兴趣的:(scala)