Scala面向物件和模式匹配
阿新 • • 發佈:2019-01-06
我們要封裝資料,定義模板等操作,所以我們需要面向物件。
一、scala中的單例物件
在scala當中,是沒有static的,scala給我們提供了單例模式的實現方法。就是使用關鍵字object。
static在java中修飾屬性和方法,目的是直接類名.進行呼叫。
在scala中object是一個單例物件
在scala中object定義的成員變數和方法都是靜態的
可以通過 類名. 來進行呼叫
1、ScalaTest
object ScalaTest { //定義成員變數 val name: String = "tom" //定義方法public staticdef 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)) }
結果: