1. 程式人生 > >Scala面向物件和模式匹配

Scala面向物件和模式匹配

我們要封裝資料,定義模板等操作,所以我們需要面向物件。

一、scala中的單例物件

    在scala當中,是沒有static的,scala給我們提供了單例模式的實現方法。就是使用關鍵字object。
    static在java中修飾屬性和方法,目的是直接類名.進行呼叫。
在scala中object是一個單例物件 在scala中object定義的成員變數和方法都是靜態的 可以通過 類名. 來進行呼叫

1、ScalaTest

object ScalaTest {
  //定義成員變數
  val name: String = "tom"
  //定義方法public static
def sleep(str: String): Unit = { println(str) } }

2、ScalaMain

/**
  * 在scala中object是一個單例物件
  * 在scala中object定義的成員變數和方法都是靜態的
  * 可以通過 類名. 來進行呼叫
  */
object ScalaMain {
  def main(args: Array[String]): Unit = {
    println(ScalaTest.name)
    ScalaTest.sleep("Tom睡得很香!")
  }
}

結果:

二、scala類與構造器的使用

    scala中主構造器:
    定義在類名後面的構造器叫主構造器
    scala輔助構造器:
    定義在class類中,可以有多個輔助構造器
    
    如果主構造器中成員變數屬性沒有被val var修飾的話,該屬性不能被訪問
    相當於java中沒有對外提供get方法

    如果成員屬性使用var修飾的話,相當於java中對外提供了get方法和set方法
    如果成員屬性使用val修飾的話,相當於java中對外只提供了get方法

1、Person1

//定義類
class Person1 {
  //定義姓名 年齡
  var name: String = _
  var age: Int 
= _ } //繼承App特質 可以不寫main object Test extends App{ val p = new Person1 p.name = "tom" p.age = 18 println(p.name) }

2、Person2

//定義主構造器
class Person2(name:String,age:Int) {

}

object Test2 extends App{
  val p = new Person2("john",19)
  println(p)
}

結果:

3、Person3

class Person3(var name:String,age:Int) {
  var high:Int = _
  var weight:Int = _

  //定義輔助構造器
  def this(name:String,age:Int,high:Int){
    //注意:在輔助構造器中必須先呼叫主構造器
    this(name,age)
    this.high = high
  }

  //輔助構造器可以是多個
  def this(name:String,age:Int,high:Int,weight:Int){
    /*
      如果主構造器中成員變數屬性沒有被val var修飾的話,該屬性不能被訪問
      相當於java中沒有對外提供get方法

      如果成員屬性使用var修飾的話,相當於java中對外提供了get方法和set方法
      如果成員屬性使用val修飾的話,相當於java中對外只提供了get方法
     */
    this(name,age)
    this.weight = weight
  }
}

object Test3 extends App{
  val p1 = new Person3("tom",18)
  println(p1.name)
}

結果:

三、構造器的訪問許可權

在主構造器或者輔助構造器前加上private修飾符即可

1、Person4

/*
  類的構造器訪問許可權:
  private 私有
 */
//主構造器設定為私有
class Person4 private (var name:String,age:Int) {

  var high: Int = _
  private def this(name:String,age:Int,high:Int){
    this(name,age)
    this.high = high
  }
}

2、ScalaDemo

object ScalaDemo {
  def main(args: Array[String]): Unit = {
    //被private 修飾的主構造器 對外訪問許可權
    val p = new Person4("hh",88)
    val p2 = new Person4("ff",33,190)
    println(p.name)
    println(p2.name)
  }
}

結果:

四、類的訪問許可權

1、Person5

/**
  * 類的前面如果加上包名,表示當前類在當前包及其子包可見,可以訪問
  * [this}預設是它,表示當前包都有訪問許可權
  */
private[this] class Person5(var name:String,age:Int) {
  var high:Int = _

  def this(name:String,age:Int,high:Int){
    this(name,age)
    this.high = high
  }
}

2、Test

object Test {
  def main(args: Array[String]): Unit = {
    val p = new Person5("dd",18,188)
    println(p.name)
  }
}

五、伴生物件

1、Person6

class Person6(private var name:String,age:Int) {
  var high:Int = _

  def this(name:String,age:Int,high:Int){
    this(name,age)
    this.high = high
  }
}

//注意:在伴生物件中可以訪問類的私有成員方法和屬性
//什麼是伴生物件? 單例類名和類名相同
object Person6 extends App{
  val p = new Person6("tom",18,180)
  println(p.name)
}

六、特質

相當於java中Interface介面。

1、Animal

trait Animal {
  //定義未實現的方法
  def eat(name:String)

  //定義實現的方法
  def sleep(name:String): Unit = {
    println(s"$name -> 在睡覺")
  }
}

2、Pig

object Pig extends Animal {
  override def eat(name: String): Unit = {
    println(s"$name -> 在吃飯")
  }

  override def sleep(name: String): Unit = {
    println(s"$name -> 做夢吃雞")
  }

  def main(args: Array[String]): Unit = {
    Pig.eat("john")
    Pig.sleep("tom")
  }
}

結果:

七、混入特質

1、Animal

trait Animal {
  //定義未實現的方法
  def eat(name:String)

  //定義實現的方法
  def sleep(name:String): Unit = {
    println(s"$name -> 在睡覺")
  }
}

2、Running

trait Running {
  def how(str:String): Unit = {
    println(s"$str -> 在奔跑")
  }
}

3、Dog

//混入特質
object Dog extends Animal with Running {
  override def eat(name: String): Unit = {
    println(s"$name -> 吃骨頭")
  }

  override def sleep(name: String): Unit = {
    println(s"$name -> 長膘")
  }

  def main(args: Array[String]): Unit = {
    Dog.eat("小狗")
    Dog.how("金毛")
  }
}

結果:

八、抽象類

1、AbstractDemo

//定義抽象類
abstract class AbstractDemo {
  def eat(food:String)

  def sleep(how:String): Unit = {
    println(s"$how -> 睡得很香")
  }
}

2、AbstractImpl

//繼承抽象類可以再繼承特質 但是抽象類寫在前 用with連線
object AbstractImpl extends AbstractDemo with Running {
  override def eat(food: String): Unit = {
    //ctrl + i
    println(s"$food -> 吃火鍋")
  }

  def main(args: Array[String]): Unit = {
    AbstractImpl.eat("tom")
    AbstractImpl.how("john")
  }
}

結果:

九、模式匹配

1、MatchTest

//模式匹配
object MatchTest {
  def main(args: Array[String]): Unit = {
    def strMatch(str:String) = str match {
      case "john" => println("很帥")
      case "mary" => println("很美")
      case _ => println("你是誰?")
    }
    strMatch("john")

    def arrayMatch(arr:Any) = arr match {
      case Array(1) => println("只有一個元素的陣列")
      case Array(1,2) => println("有兩個元素的陣列")
    }
    arrayMatch(Array(1,2))

    def tuple(tuple:Any) = tuple match {
      case (1,_) => println("元組的第一個元素為1,第二個元素任意")
      case ("tom",18) => println("這是個帥小夥")
    }
    tuple("tom",18)
  }
}

結果:

十、final關鍵字

    如果方法不想被重寫可以使用final關鍵字進行修飾
    用final修飾的:
    類:類不能被繼承
    方法:不能被重寫
    val

1、Animal

trait Animal {
  //定義姓名
  final var name:String = "tom"
  var age:Int = 18

  def eat(name: String)

  final def sleep(name: String): Unit = {
    println(s"$name -> 睡得天花亂墜")
  }
}

2、Pig

object Pig extends Animal {
  //重寫eat方法
  override def eat(name: String): Unit = {
    println(s"$name -> 吃吃吃")
  }

  //這裡編譯報錯,final修飾方法不能被重寫
  override def sleep(name: String): Unit = {
    println(s"$name -> 做夢吃雞")
  }

  def main(args: Array[String]): Unit = {
    Pig.eat("豬")
    Pig.sleep("john")
    Pig.name = "john tom"
    println(Pig.name)
  }
}

十一、type關鍵字

    別名設定
    使我們的程式變得更靈活
    T

1、Anl

trait Anl {
  //定義特質時可以不指定型別
  type T

  def sleep(str: T): Unit = {
    println(str)
  }
}

2、AnlTest

object AnlTest extends Anl {
  override type T = String

  def main(args: Array[String]): Unit = {
    AnlTest.sleep("睡得很香")
  }
}

結果:

十二、樣例類和樣例物件

    1)樣例類
    樣例類支援模式匹配
    寫法:case class 類名(屬性...)
    2)樣例物件
    寫法:case object 類名(屬性...)
    不能封裝資料
    支援模式匹配
    case object Check
    match{
        case "Check" => println(Check)
    }

1、TestEat

//樣例類支援模式匹配
case class Eat(food:String,drink:String)

object TestEat {
  def main(args: Array[String]): Unit = {
    val eat = new Eat("麻辣香鍋","北冰洋")
    println(eat)
  }
}

2、TestEat1

//樣例類支援模式匹配
case class Boy(high:Int,weight:Int)
case class Girl(high:Int,weight:Int)

object TestEat1 extends App {
  def objMatch(obj:Any) = obj match {
    case Boy(x,y) => println(s"$x $y 的男孩")
    case Girl(x,y) => println(s"$x $y 的女孩")
  }

  objMatch(Boy(180,120))
  objMatch(Girl(160,90))
}

結果: