scala的面向物件
面向物件
1.物件:用object修飾的語法結構
2.類:用class修飾的
3.類的例項:new 類() 類的例項
4.面向物件的三大特徵
(1)封裝
(2)繼承
(3)多型
5.抽象類
6.Trait(介面)
物件
Object
1.單例的,靜態的,scala中根本沒有static關鍵字,為了彌補scala中沒有static關鍵字,scala中使用object代替
2.Static:object代替了static的功能
3.Object本身,沒有構造方法,但是他可以定義成員變數和成員屬性,不能new
伴生物件
是一類特殊的物件,類和物件相伴而生,物件稱之為類的伴生物件,類稱之為物件的伴生類
伴生的條件
1.object的名稱必須和類的名稱一樣
2.必須在同一個原始檔中,在同一個scala檔案中
特點:可以相互訪問物件的私有成員屬性和方法
class HelloScala {
private val name = "taotao"
}
object HelloScala {
def main(args: Array[String]): Unit = {
val h1: HelloScala = new HelloScala()
val name: String = h1.name
println(name)
}
}
//輸出
taotao
物件上有一個特殊的方法:Apply
Apply有一個功能:建立例項
物件()—>預設呼叫的是該物件中的apply方法
def apply(): ApplyDemo = new ApplyDemo()
//定義一個apply的過載方法
def apply(x: Int, y: Int): Int = {
x * 10 + y * 10
}
def main(args: Array[String]): Unit = {
//相當於呼叫了ApplyDemo.apply()方法
println(ApplyDemo())
//相當於呼叫了ApplyDemo.apply(10,20)方法
val result: Int = ApplyDemo(10, 20)
println("result:" + result)
val result2: Int = ApplyDemo.apply(10, 20)
println("result2:" + result2)
val result3: Int = apply(10, 20)
println("result3:" + result3)
}
//輸出
[email protected]
result:300
result2:300
result3:300
App
App特質,裡面定義了Main方法,物件extends App後,可以不用寫main
object AppDemo extends App {
//繼承了APP以後,就相當有了main方法,可以直接執行
println("12345")
}
//輸出
12345
類
成員屬性,成員方法(object中也有成員方法)
class Person { //定義一個變數 //val隱藏了get方法,var隱藏了get和set方法 val name: String = "taotao" //_是佔位符,待指的意思,可以變化 var age: Int = _ def speak() = { println("你聽過一首哲理的歌麼?") } //alt+fn+insert //重寫toString override def toString = s"Person($name, $age)" } object Person { def sing() = { println("這裡的山路十八彎") } def main(args: Array[String]): Unit = { val p: Person = new Person() val name: String = p.name p.age = 20 val age: Int = p.age println(name + " " + age) //插值法輸出,字串前面加s,用$去引用就ok println(s"name=${p.name},age=${p.age}") p.speak() //可以呼叫伴生類中的成員方法 Person.sing() } } //輸出 taotao 20 name=taotao,age=20 你聽過一首哲理的歌麼? 這裡的山路十八彎
注意:
1.val修飾的變數,只能有get方法
2.Var修飾的變數,可以有get和set方法
3.如果重寫toString,則ALT+Fn+INSERT
構造器
1.scala中的構造器,類似java中的構造器
2.Scala中的構造器分為兩類:主構造器和輔助構造器
3.主構造器只有一個,輔助構造器可以有多個
class Student(val name: String, val age: Int) {
//無參輔助構造器
def this() = {
//輔助構造器的第一行,必須呼叫主構造器,或者其他的輔助構造器
this("taotao", 20)
}
var scc: String = _
//有參的輔助構造器,賦值語句需要寫在第一行
def this(name: String, age: Int, scc: String) = {
this(name, age)
this.scc = scc
}
override def toString = s"Student($scc, $name, $age)"
}
object Student {
def main(args: Array[String]): Unit = {
//呼叫類的無參構造器,預設使用主構造器
val student1: Student = new Student()
println("主構造器:"+student1)
val student: Student = new Student("huahua", 19)
println("輔助構造器:"+student)
println(s"${student.name},${student.age}")
val stu: Student = new Student("taotao", 20, "xixi")
println(stu)
}
}
//輸出
主構造器:Student(null, taotao, 20)
輔助構造器:Student(null, huahua, 19)
huahua,19
Student(xixi, taotao, 20)
注意:
1.主構造器的作用域,是在他整個類的大括號範圍之內,除了定義的方法,全是他的作用域
2.主構造器只能有一個,和類的定義交織在一起
3.輔助構造器的使用,def this(引數列表),來定義
4.主構造器中的變數,使用val和var來宣告,就是成員屬性,在外部也可以訪問,如果不加修飾符,只能在類的內部使用引數名稱而已
5.輔助構造器的第一行,必須呼叫主構造器或者其他的輔助構造器
6.主構造器的引數必須要賦值
7.輔助構造器的引數不能和主構造器的引數和結構一致
優先使用主構造器
訪問許可權
指的是成員方法和成員屬效能不能在其他訪問的到
成員屬性:
預設的訪問許可權:共有的
方法:普通方法和構造器
class Girls private(val age: Int) {
//私有的
//如果類中有私有屬性,不想在其的伴生物件中訪問到,那麼
//private[this] 如果是這種格式,只有本類中才能訪問
//還可以在private[包的名字]讓屬性在哪些包以及子包中可以訪問的到
private val name = "taotao"
def this() {
this(11)
}
}
object Girls {
//伴生物件可以訪問伴生類私有的屬性和方法,其他類中不可以
def main(args: Array[String]): Unit = {
val girls: Girls = new Girls(11)
val name: String = girls.name
println(name + " " + girls.age)
}
}
//輸出
taotao 11
注意:
1.一般情況下,我們根本不會刻意去加private許可權,以後只要知道在哪家就可以了
2.預設的訪問許可權是公有的
3.Private 在當前類,伴生物件中可以訪問,在其他的地方無法訪問
4.Private[this] 只有在當前類中有效,其他地方都無效
5.Private[包名]在指定包的下面都有效
抽象類
Abstract修飾
特點:可以有抽象方法,例項方法,不能new,抽象類有構造器
特質 Trait
Trait:類似於java中的介面,功能更加強大,混入特質:extends和with
特質裡是沒有構造器的
Java中的介面:interface —》implements
多實現
Java中的介面,可以寫實現類
特點,沒有構造器,有抽象方法,非抽象方法
1.子類繼承父類,呼叫extends,如果混入特質,用extends,with
2.當沒有顯示父類時候,第一個必須呼叫extends,其他特質都用with
模式匹配
1.match+一系列的case(條件)=>
2.模式匹配是有返回值的
(1)匹配內容
(2)匹配型別
(3)匹配陣列
(4)匹配元組
(5)匹配list集合
(6)匹配樣例類和樣例物件
(7)匹配option(some,none)
匹配內容:
val arr: Array[String] = Array("taotao", "huahua", "jianjian")
//隨機獲取索引
val num: Int = Random.nextInt(arr.length)
println(num)
arr(num) match {
case "taotao" => println("哈哈哈")
case "huahua" => println("嘻嘻嘻")
case "jianjian" => println("嘿嘿嘿")
//解決匹配不上的問題
case _ => println("nomatch")
}
//輸出
0
哈哈哈
匹配型別:
val array: Array[Any] = Array[Any](10, 6.6, "taotao")
val num: Int = Random.nextInt(array.length)
println("抽到第:" + num + 1)
array(num) match {
//加守衛
case x: Int if x > 10 => println(x)
case y: Double => println(y)
case z: String => println(z)
//匹配不到的,帶守衛的匹配不上,到這裡
case _ => println("no match")
}
//輸出
抽到第:11
6.6
匹配陣列:
整體的匹配:
val arr: Array[Int] = Array[Int](1, 3, 4, 5, 6)
arr match {
case Array(a, b, x, y, z) => println(s"a=${a},b=${b},x=${x},y=${y},z=${z}")
case Array(1, _*) => println("match")
}
//輸出
a=1,b=3,x=4,y=5,z=6
匹配元組:
要求最大值和最小值一起返回
//接收方式
val (max, min) = getValues(Array(1, 3, 5, 7, 8, 3, 9, 0))
val tp2 = getValues(Array(1, 3, 5, 7, 8, 3, 9, 0))
val tp1 = (tp2._1, tp2._2, true)
println("tp1:"+tp1)
val tp = (max, min, true)
tp match {
case (x, y, z) => println(s"x=${x},y=${y},z=${z}")
case (x, _, _) => println(x)
case _ => println("no match")
}
//輸出
tp1:(9,0,true)
x=9,y=0,z=true
匹配list集合
val list1: List[Int] = List[Int](1, 3, 4)
list1 match {
case List(x, y, z) => println(s"x=${x},y=${y},z=${z}")
// x為頭元素,y為尾元素
case x :: y => println(s"x=${x},y=${y}")
// x::y::Nil這樣是不可以的,因為有Nil的時候為具體元素,少一個z是不可以的
case x :: y :: z :: Nil => println(s"x=${x},y=${y},z=${z}")
case _ => println("no match")
}
//輸出
x=1,y=3,z=4
匹配樣例類和樣例物件
1、樣例類:
(1)特殊的類:case class person
(2)樣例物件:case object person
(3)樣例類的特點:
①樣例類,不能new
②Case class 必須有主構造器
③預設實現了,equals,hashcode,toString
④實現序列化特質
scala> case class person(name:String,age:Int)
defined class person
scala> val p1=person("li",27)
p1: person = person(li,27)
scala> val p2=person("li",27)
p2: person = person(li,27)
scala> p1==p2
res0: Boolean = true
樣例類支援模式匹配樣例
匹配option
val map: Map[String, Int] = Map[String, Int]("a" -> 100, "b" -> 200, "c" -> 300)
//取值get
val maybeInt: Option[Int] = map.get("a")
val result: Int = maybeInt match {
case Some(v) => v
case None => -1
}
println(result)
//輸出
100
偏函式
Def 方法名稱 partialFunction[輸入引數,返回值型別]={
Case xx=>xx
}
省略match
def meth1(name: String): Int = name match {
case "taotao" => 100
case "huahua" => 90
case _ => -1
}
def pf: PartialFunction[String, Int] = {
case "taotao" => 100
case "huahua" => 90
case _ => -1
}
def pf2: PartialFunction[Any, Int] = {
case x: Int => x * 10
case _ => -1
}
def main(args: Array[String]): Unit = {
println(meth1("taotao"))
println(pf("taotao"))
val arr: Array[Any] = Array[Any](1, 2, 4, 5, "error")
val num: Array[Int] = arr.map(pf2)
println(num.toList)
//還有一些具體的方法必須偏函式
val num1: Array[Int] = arr.collect(pf2)
println(num1.toList)
}
//輸出
100
100
List(10, 20, 40, 50, -1)
List(10, 20, 40, 50, -1)