scala (二)

scala第三章

面向對象

下劃線的作用:
1.導依賴,代表應用某個包的全部類

2.方法和函數轉換,代表轉換的過程

3.傳參,代表一個元素

4.聲明字段,代表賦初始值

5.元組的取值,代表獲取與元組的某個元素

java面向對象

類:類是一類事物的抽象

對象:對象是一個實例

java修飾符

​ 當前類,同一個包內,子類,其他包

private Y N N N

public Y Y Y Y

protected Y Y Y N

(default) Y Y N N

scala面向對象

class  PersonS{
  //val 修飾的屬性:jvm會自動生成get方法
  val id:String="1234"
  def getid():String={
    println(id)        
    this.id
  }
  //var 修飾的屬性:jvm會自動生成set get方法
  var name:String=""
  //private var修飾的屬性:jvm會自動生成private的set get 方法
  //相當於類的私有字段
  private var gender:Int=0
  //private[this] var修飾的屬性:jvm不會生成set get 方法
  //只有當前對象可以訪問該屬性
  private [this] var age:Int=0
//  def compare(obj:Test):Int={
//    this.age
//  }

}
object test{
  def main(args: Array[String]): Unit = {
    var per:PersonS=new PersonS()
    //println(per.id)
    println(per.getid())
    per.name=("zhangsan")
    println(per.name)

  }
}

構造方法

scala主構造函數
class CoustruorDemo(b:Int) { 
  var a:Int=b
  println("Construtor Study")
  //定義輔助構造函數
//  def this(al:Int){
//    //首先調用主構造函數或其他的輔助構造函數
//    this()
//    this.a=al
//  }

}
jvm中的scala主構造函數(無 var b)
import scala.Predef.;
import scala.reflect.ScalaSignature;
public class CoustruorDemo
{
  private int a;

  public int a()
  {
    return this.a; } 
  public void a_$eq(int x$1) 
  { 
      this.a = x$1; 
  } 
  public CoustruorDemo(int b) 
  { 
    this.a = b;
    Predef..MODULE$.println("Construtor Study");
  }
}
jvm中的scala主構造函數(var b)
import scala.Predef.;
import scala.reflect.ScalaSignature;
public class CoustruorDemo
{
  private final int b;
  private int a;

  public int b()
  {
    return this.b; } 
  public int a() 
  { return this.a; } 
  public void a_$eq(int x$1) 
  { this.a = x$1; } 
  public CoustruorDemo(int b) { 
    this.a = b;
    Predef..MODULE$.println("Construtor Study");
  }
}

在這裏插入圖片描述

單例對象
//定義一個私有的主構造函數
//定義一個帶有參數的主構造函數
class CoustruorDemo private  (val b:Int) {
  var a:Int=b
  println("Construtor Study")
  //定義輔助構造函數
//  def this(al:Int){
//    //首先調用主構造函數或其他的輔助構造函數
//    this()
//    this.a=al
//  }
//類自帶無參的構造函數
//主構造函數會執行類中定義的所有語句
//主構造函數和輔助構造函數
//定義輔助構造函數
  def this(a1:Int,b1:Int){
    this(b1)
    this.a=a1
  }

//  def this(a2:Int,b2:Int){
//    this(b2)
//    this.a=a2
//  }
}

object  CoustruorDemoTest{
  def main(args: Array[String]): Unit = {
//    val demo:CoustruorDemo=new CoustruorDemo()
//      val demo:CoustruorDemo=new CoustruorDemo(100)
//    println (demo.a)
  }
}
/單例對象
//可以看做java工具類,可以定義一些工具函數和常量
//單例對象不能帶參數
//單例對象在第一次使用的時候初始化
object Logger {
  def main(args: Array[String]): Unit = {

  }
  def log(msg:String):Unit={
    println(s"INFO:$msg")
  }
}

class Test{
  def method={Logger.log("scala")}
}
object  LoggerTest{
  def main(args: Array[String]): Unit = {
    Logger.log("java")
    val  te:Test=new Test();
    te.method
  }
}
伴生對象(應用程序對象執行程序)
class AccountInfo {
    var id = AccountInfo.newUnqueNumber
    var id2= AccountInfo.lastNumber
}
//類的伴生對象,伴生對象和類可以互相訪問彼此的私有屬性和方法
object AccountInfo{
  private  var lastNumber=0
  private def newUnqueNumber={
    lastNumber+=1
    lastNumber
  }


}
//單例對象測試
//object companionTest{
//  def main(args: Array[String]): Unit = {
//    var obj:AccountInfo=new AccountInfo()
//    println(obj.id)
//  }
//}
//應用程序對象
//scala語言執行的入口 相當於main方法
object companionTest extends App{
  var obj:AccountInfo=new AccountInfo()
  println(obj.id)
}
Apply和unApply方法
class User (val name:String,val password:String){

}
object User{
  def apply(name:String,password:String)=new User(name,password)

  def unapply(arg: User): Option[(String, String,String, String)] ={
    if(arg==null)None
    else{
      Some(arg.name,arg.password,arg.name,arg.password)
    }
  }
}
object userTst{
  def main(args: Array[String]): Unit = {
    //val obj =new User("zbs","123456")
    //調用伴生對象的apply方法(少了new)
    val obj=User("zbs","123456")
  println(obj.name+obj.password)
    obj match {
      case User(name,password,name1,password1)=>println(name+":"+password)(提取User中的unapply的注入)
      case _=>println("None")
    }
  }
}
繼承
class Point(val xc: Int, val yc: Int) {
  var x: Int = xc
  var y: Int = yc

   def  move(dx: Int, dy: Int) = {
    x = x + dx
    y = y + dy
    println("x:" + x)
    println("y:" + y)

  }
}

//override重寫屬性(父類)
class Location(override val xc: Int, override val yc: Int, val zc: Int) extends Point(xc, yc) {
  var z: Int = zc

  def move(dx: Int, dy: Int, dz: Int) = {
    x = x + dx
    y = y + dy
    z = z + dz
    println("x座標:" + x)
    println("y座標:" + y)
    println("z座標:" + z)
  }
}

//繼承了父類的所有屬性和方法
//重寫父類的非抽象方法,要用override
//重寫父類的抽象方法,override可選擇
//final修飾的類,方法,屬性,不能被重寫(或者繼承)
object testClass {
  def main(args: Array[String]): Unit = {
    val obj = new Location(5, 6, 7)
    obj.move(1, 2, 3)
    val obj1 = new Point(80, 100)
    //判斷對象是否屬於給定的類
    obj.isInstanceOf[Location]
    //類型轉換
    obj.asInstanceOf[Point]
    //獲取類的信息
    println(classOf[Location])

  }
}

抽象類

abstract class Person {
  //抽象字段,沒有初始化值
  var name: String

  def id: Int
  //具體的方法
  def smile={
    println("123456")
  }
}

class Employ extends Person {
  var name: String = "jerry"

  def id: Int = {
    name.hashCode
  }

  override def smile: Unit = super.smile
}
//特質還是抽象類?
//優先使用特質
特質
//定義一個帶有抽象方法的特質
trait Iterator[A]{
  def hasNext:Boolean
  def next():A
}
//定義一個帶有實現的特質
trait ConsoleLogger{
  def log(msg:String)={
    println(msg)
  }
}
//定義一個類實現特質(多特質用with)
class IntIterator(to:Int) extends Iterator[Int] with ConsoleLogger {
  private  var current=0
  override def hasNext=current < to
  override def next():Int ={
    if(hasNext){
      log("hasnext")
      val t=current
      current+=1
      t
    }else 0
  }
}
object TraitTest {
  def main(args: Array[String]): Unit = {
    val iterator = new IntIterator(10)
    println(iterator.next())
    println(iterator.next())
    println(iterator.next())
  }
}
特質的應用
//測試特質爲類提供可以堆疊的改變(混入的特質順序不同,結果可能也是不同的(特質執行順序不一樣))
trait Logger{
  def log(mag:String)
}
//子特質實現父特質的抽象方法
trait ConsoleLogger extends Logger{
  override def log(msg:String)=println(msg)
}
//給日誌加上時間戳
trait TimestampLogger extends ConsoleLogger{
  override def log(msg: String): Unit = super.log(s"${java.time.Instant.now()}$msg")
}
//如果日誌過長,對日誌截斷顯示
trait ShortterLoger extends ConsoleLogger{
  val maxLength=15

  override def log(msg: String): Unit = super.log(
    if(msg.length<=maxLength)msg
    else s"${msg.substring(0,maxLength-3)}..."
  )
}
class Account{
  protected var balance=0.0;


}
class SavingAccount extends Account with ConsoleLogger {
  def withDraw(amount:Double)={
    if(amount>balance){
      log("Insufficent funds")
    }else balance=balance-amount
  }
}
object TraitTest2 {
  def main(args: Array[String]): Unit = {
//    var acc1=new SavingAccount with ConsoleLogger with TimestampLogger with ShortterLoger
//    var acc2=new SavingAccount with ConsoleLogger with ShortterLoger with TimestampLogger
//    acc1.withDraw(100)
//    acc2.withDraw(100)
    var acc1 = new SavingAccount with ConsoleLogger
    acc1.withDraw(100.0)
    var  acc2 = new SavingAccount with  ConsoleLogger with  TimestampLogger
    acc2.withDraw(100.0)
    var  acc3 = new SavingAccount with  ConsoleLogger with  ShortterLoger
    acc3.withDraw(100.0)
  }
}

特質的其他應用
trait Logger1{
  def log(msg:String)
  def info(msg:String){log("Info:"+msg)}
  def severce(msg:String){log("serverce"+msg)}
  def warn(msg:String){log("warn"+msg)}
}
//作爲接口使用,擴展類的功能
class Account{
  protected var balance=0.0

}
class SavingAccount1 extends Account with Logger1 {
  override def log(msg: String): Unit = println(msg)
  def withDarw(amount:Double)={
    if(amount > balance) severce("Insufficent funds") else{
      balance=balance-amount
      info("you withdraw...")
    }
  }
}
object TraitTest3 {
  def main(args: Array[String]): Unit = {
    val acc=new  SavingAccount1
    acc.withDarw(100.0)
  }
}

lazy修飾符

scala中的懶加載

object ScalaLazyDemo2 {
  def init(): Unit = {
    println("init")
  }

  def main(args: Array[String]): Unit = {
    lazy val prop = init() // 沒有用lazy修飾符修飾的變量

    println("after init()")

    println(prop)

  }
}
init
after init ()
()

scala第四章

樣例類

object CascclassDamo {
  def main(args: Array[String]): Unit = {
    //定義樣例類
    //一旦定義樣例類默認帶有apply方法
    //構造函數的參數默認是public val修飾的
    case class Message(send: String, rccipicnt: String, body: String)
    //創建一個樣例類的對象
    val message1 = Message("Jerry", "Tom", "Hello")
    println(message1.send)
  // 樣例類的比較,是基於值或者結構比較,而不是基於引用比較
    val message2=Message("Jerry","Tom","Hello")
    if(message1==message2){
     println("same")//結構是same
    }else{println("defferent")}
    //樣例類的copy
    val message3=message1.copy()
    println(message3.send+".."+message3.rccipicnt+".."+message3.body)
    if(message2==message3){
      println("same")//結構是same
    }else{println("defferent")} 
    //不完全拷貝,對部分參數賦值
    val message4=message1.copy(send = "hanmeimei")
    println(message4.send+".."+message4.rccipicnt+".."+message4.body)
  }

}

模式匹配

java switch

常量模式匹配

變量模式匹配

通配符模式匹配

object PatternDemo {
  def main(args: Array[String]): Unit = {
    //常量模式匹配
    //常量字面值匹配
    //    val site ="scala.com"
    //    val SCALA="qianfeng.com"
    //    site match {
    //      case "scala.com"=>println("success")
    //      //相當於java中的default
    //        //不需要break語句
    //      case _=>println("fail")
    //
    //    }

    //    //變量的匹配
    //    val site ="scala.com"
    //    val SCALA="scala.com"
    //    val scala="sca.com"
    //    site match {
    //        case SCALA=>println(scala) //常量變量的值必須是大寫(小寫會認爲是變量,會把值賦給小寫變量)
    //      //相當於java中的default
    //      //不需要break語句
    //      case _=>println("fail")
    //
    //    }
    //    //變量模式匹配
    //    val site ="scala.com"
    //    val scala="sca.com"
    //    site match {
    //      case scala=>println(scala+" success")//變量,會把值賦給小寫變量
    //      //相當於java中的default
    //      //不需要break語句
    //      case _=>println("fail")
    //
    //    }
    //  }
    //通配符模式
    val list = List(1, 2, 4)
    list match {
      case List(_, _, 3) => println("success")
      case _ => println("fail")
    }
  }
}

樣例類匹配

類型匹配

object PattenDemo2 {
  def main(args: Array[String]): Unit = {
    //做一個信息的甄別
    abstract class Notification
    //不同信息的樣例類
    case class Email(send: String, tile: String, body: String) extends Notification
    case class SMS(caller: String, message: String) extends Notification
    case class VoiceRecording(contactName: String, link: String) extends Notification
    //信息的識別
    def showNotification(notification: Notification):String={
      notification match {
          //可以加判斷
        case Email(send,tile,_) if(send=="zhangjin")=> "you get an important Eail message from "+send
        case SMS(caller,message)=>"you get  a SMS message from "+caller
        case VoiceRecording(contactName,link)=>"you get a VoiceRecording message from"+contactName
        case _=>"you get a message "
      }
    }
    //創建一條信息
    val email:Email=new Email("zhangjin","angaoshan","somemmmm")
    val email2:Email=new Email("ls","angaoshan","somemmmm")
    println(showNotification(email))
    println(showNotification(email2))
  }
}
object Test3{
  //類型匹配
  def main(args: Array[String]): Unit = {
    val array=Array("sss",1,2,3,'c')
    //隨機抽取數組中的一個元素
    val obj = array(Random.nextInt(4))
    println(obj)
    obj match {
      case x:Int => println(x)
      case s:String=> println(s.toUpperCase())
      case d:Double=>println(Int.MaxValue)
      case _=>println("fw")
    }
  }

}

匹配字符串、數組、列表、元組

字符串匹配

/**
  * 模式匹配-字符串
  */
object MatchString {
  def main(args: Array[String]): Unit = {

    val arr = Array("zhoudongyu", "yangzi", "guanxiaotong", "zhengshuang")

    val name = arr(Random.nextInt(arr.length))

    println(name)

    name match {
      case "zhoudongyu" => println("周冬雨")
      case "yangzi" => println("楊紫")
      case "guanxiaotong" => println("關曉彤")
      case "zhengshuang" => println("鄭爽")
      case _ => println("Nothing ...")
    }

  }
}

數組匹配

對Array進行模式匹配,分別可以匹配帶有指定元素的數組、帶有指定個數元素的數組、以某元素打頭的數組.

  val arr1 = Array(1,1)
  val res = arr1 match {
  case Array(0) => "0"
  //匹配包含0的數組
  case Array(x, y) => s"$x $y"
  // 匹配任何帶有兩個元素的數組,並將元素綁定到x和y
  case Array(0, _*) => "0..."
  //匹配任何以0開始的數組
  case _ => "something else"
}

列表匹配

val lst = List(1,2)
val res2 =  list match {
   case 0 :: Nil => "0"
   case x :: y :: Nil => x + " " + y
   case 0 :: tail => "0 ..."
   case _ => "something else"
 }

元組匹配

var pair = (1,2)
val res3 =  pair match {
  case (0, _)  => "0 ..."
  case (y, 0) => s"$y 0"
  case _ => "neither is 0"
}

偏函數

object PartialFunctionDemo {
  //創建一個普通函數
  val div1 = (s: Int) => 100 / s
  //定義一個偏函數
  val div2 = new PartialFunction[Int, Int] {
    override def isDefinedAt(x: Int): Boolean = x != 0

    def apply(x: Int) = 100 / x
  }
  //使用case 定義偏函數
  val div3: PartialFunction[Int, Int] = {
    case d: Int if (d != 0) => 100 / d
  }
  val res: PartialFunction[Int, String] = {
    case 1 => "one"
    case 2 => "two"
    case _ => "other"
  }
  //orElse 組合多個偏函數變成一個整體
  val r1: PartialFunction[Int, String] = {
    case 1 => "one"
  }
  val r2: PartialFunction[Int, String] = {
    case 2 => "two"
  }
  val r3: PartialFunction[Int, String] = {
    case _ => "other"
  }
  var res2 = r1 orElse r2 orElse r3 //相當於res這個偏函數
  //andThen
  val r4: PartialFunction[Int, String] = {
    case cs if (cs == 1) => "one"
  }
  val r5: PartialFunction[String, String] = {
    case cs if (cs eq "one") => "china number one"

  }
  val res3 :(Int=>String)=r4 andThen r5
  def main(args: Array[String]): Unit = {
    //   println(div2.isDefinedAt(1))
    //    div2(1)
    //    println(div2.isDefinedAt(0))
    //    div2(0)
    //    println(div3.isDefinedAt(1))
    //    div3(1)
    //    println(div3.isDefinedAt(0))
    //    div3(0)
    println(res2(4))
    println(res2.isDefinedAt(7)) //true
    println(res3(1))
  }
}
object PartialFunctionDemo {
  //創建一個普通函數
  val div1 = (s:Int)=> 100/s
  //定義一個偏函數
  val div2 = new PartialFunction[Int,Int] {
      override def isDefinedAt(x: Int): Boolean = x!=0
      def apply(x:Int)=100/x
  }
  //使用case 定義偏函數
  val div3:PartialFunction[Int,Int]={
    case d:Int if(d!=0)=>100/d
  }
  val res:PartialFunction[Int,String]={
    case 1=>"one"
    case 2=>"two"
    case _=>"other"
  }
  def main(args: Array[String]): Unit = {
//   println(div2.isDefinedAt(1))
//    div2(1)
//    println(div2.isDefinedAt(0))
//    div2(0)
//    println(div3.isDefinedAt(1))
//    div3(1)
//    println(div3.isDefinedAt(0))
//    div3(0)
    print(res(4))

  }
}

密封類

用關鍵字sealed修飾的類或者特質

約束:不能再類定義文件之外定義它的子類

作用1:可以避免濫用繼承

作用2:用在模式匹配中(因爲是密封類,所以可以確定子類的個數,在模式匹配中有確定的選項)

sealed abstract class Furniture
case class Couch() extends Furniture
case class Chair() extends Furniture
object  Test6{
  def findPlaceToSit(furniture: Furniture):String=furniture match {
    case a:Couch=>"lie on the couch"
    case b:Chair=>"sit on the chair"
    //case _=>""//此項不用寫
  }
  val chair = Chair()

  def main(args: Array[String]): Unit = {
      println(findPlaceToSit(chair))
  }
}

option

object OptionDemo {
  def main(args: Array[String]): Unit = {
    val map=Map("a"->"123","b"->"222")
    //println(map("a"))
    //println(map("c"))//不存在包異常
    val a:Option[String]=map.get("c")//option避免異常的出現,可以對option的結果再處理
    println(a)//
    println(map.getOrElse("c",-1))
  }
}

字符串插值器

object StringDemo {
  def main(args: Array[String]): Unit = {
    //插值器 f s raw
    //s 字符串插值器
    val name = "Jerry"
    val res = s"Hello,$name"
    //對${表達式}裏面的表達式進行運算
    val res1=s"1+1=${1+1}"
    println(res1)
  //f 插值器
    val height=1.9d
    val name1="Tom"
    val res2=f"$name1 is $height%2.2f meters tall"
    println(res2)
    //raw 插值器類似於s插值器,不對其中的內容做轉換
    val str=s"a\nb"
    println(str)
    val str2=raw"a\nb$str"
    println(str2)

  }
}
res:
1+1=2
Tom is 1.90 meters tall
a
b
a\nba
b

Process finished with exit code 0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章