大数据入门第二十天——scala入门(二)scala基础02
一、?類、對象、繼承、特質(zhì)
? 1.類
Scala的類與Java、C++的類比起來更簡潔
定義:
package com.jiangbei //在Scala中,類并不用聲明為public。 //Scala源文件中可以包含多個類,所有這些類都具有公有可見性。 class Person {// 定義一個不可變的val(只有g(shù)etter)和可變的var(getter setter都有)// 更直觀的理解,可以通過反編譯工具打開out目錄的.class文件val id = 9527var name = "唐伯虎" }當(dāng)然,變量和Java一樣可以進(jìn)行訪問控制:
//類私有字段,只能在類的內(nèi)部使用private var name: String = "唐伯虎" //對象私有字段,訪問權(quán)限更加嚴(yán)格的,Person類的方法只能訪問到當(dāng)前對象的字段
?? private[this] val pet = "小強(qiáng)"
? 構(gòu)造器:
package com.jiangbei /***每個類都有主構(gòu)造器,主構(gòu)造器的參數(shù)直接放置類名后面,與類交織在一起* 注意:主構(gòu)造器會執(zhí)行類定義中的所有語句* 如果主構(gòu)造器中的參數(shù)沒有加val var等,則為private,無法外部訪問* 構(gòu)造器參數(shù)可以不帶val或var,如果不帶val或var的參數(shù)至少被一個方法所使用,那么它將會被提升為字段* //在類名后面加private就變成了私有的class Queen private(val name: String, prop: Array[String], private var age: Int = 18){**/ class Person(var age: Int, name: String) {private var gender = "love"//用this關(guān)鍵字定義輔助構(gòu)造器def this(name: String, age: Int, gender: String){//每個輔助構(gòu)造器必須以主構(gòu)造器或其他的輔助構(gòu)造器的調(diào)用開始this(age, name)println("執(zhí)行輔助構(gòu)造器")this.gender = gender} } object Person{def main(args: Array[String]): Unit = {val p1 = new Person(18, "SMD")println(p1.age)// println(p1.name) } }? 2.對象
單例對象
在Scala中沒有靜態(tài)方法和靜態(tài)字段,但是可以使用object這個語法結(jié)構(gòu)來達(dá)到同樣的目的
1.存放工具方法和常量
2.高效共享單個不可變的實(shí)例
3.單例模式
package com.jiangbeiobject Singleton {// object中定義的方法變量的都是靜態(tài)的(靜態(tài)方法、靜態(tài)塊)def main(args: Array[String]): Unit = {val s = Singletonprintln(s) // com.jiangbei.Singleton$@5e025e70 } }伴生對象
在Scala的類中,與類名相同的對象叫做伴生對象,類和伴生對象之間可以相互訪問私有的方法和屬性
一般伴生對象和類寫在一個文件
class Person(var age: Int, name: String) {private var gender = "love"} object Person{def main(args: Array[String]): Unit = {val p1 = new Person(18, "SMD")println(p1.gender)} }apply方法
通常我們會在類的伴生對象中定義apply方法,當(dāng)遇到類名(參數(shù)1,...參數(shù)n)時(shí)apply方法會被調(diào)用
class Person() {} object Person{def apply():Unit = {println("apply被調(diào)用!")}def apply(name: String):Unit = {println(name)}def main(args: Array[String]): Unit = {// 以下的Person()會自動調(diào)用對應(yīng)的無參的apply()方法,這里的p1就是返回值了。// 如果有多個,則對應(yīng)參數(shù)相應(yīng)的val p1 = Person()val p2 = Person("小強(qiáng)")} } 結(jié)果: apply被調(diào)用! 小強(qiáng)應(yīng)用程序?qū)ο?/span>
Scala程序都必須從一個對象的main方法開始,可以通過擴(kuò)展App特質(zhì),不寫main方法。(意義不大,不常用)
object AppObjectDemo extends App{//不用寫main方法println("I love you Scala") }3.繼承
繼承:與Java保持一致,使用extands,實(shí)現(xiàn)接口使用with(with Flyable with Human)
重寫:使用override修飾符
類型轉(zhuǎn)換和類型檢查:
| Scala | Java |
| obj.isInstanceOf[C] | obj instanceof C |
| obj.asInstanceOf[C] | (C)obj |
| classOf[C] | C.class |
實(shí)例:
package com.jiangbeiobject Singleton {// object中定義的方法變量的都是靜態(tài)的(靜態(tài)方法、靜態(tài)塊)def main(args: Array[String]): Unit = {val b1 = new Birdb1.run()b1.flight()} }// 相當(dāng)于Java8的接口,可以有默認(rèn)實(shí)現(xiàn) trait Flyable {def fly(name: String): Unit = {println(name + " can fly!")}// 未實(shí)現(xiàn)方法 def flight(): Unit }abstract class Animal {val name: Stringdef run(): Unit }class Bird extends Animal with Flyable {override val name: String = "love"override def run(): Unit = {println("bird run!")}override def flight(): Unit = {println("bird flight")} }//?詳細(xì)待更新
二、模式匹配和樣例類
Scala有一個十分強(qiáng)大的模式匹配機(jī)制,可以應(yīng)用到很多場合:如switch語句、類型檢查等。
并且Scala還提供了樣例類,對模式匹配進(jìn)行了優(yōu)化,可以快速進(jìn)行匹配
? 一個模式匹配包含了一系列備選項(xiàng),每個都開始于關(guān)鍵字?case。每個備選項(xiàng)都包含了一個模式及一到多個表達(dá)式。箭頭符號?=>隔開了模式和表達(dá)式。
1.字符串匹配
def main(args: Array[String]): Unit = {val colors = Array("red", "green", "blue")val color = colors(Random.nextInt(colors.length))println("給你點(diǎn)顏色看看..")color match {case "blue" => println("藍(lán)色")case "green" => println("綠色")case "red" => println("紅色")case _ => println("不知道你在說什么..")}}2.類型匹配
def main(args: Array[String]): Unit = {val colors = Array("red", 1, 3.0)val color = colors(Random.nextInt(colors.length))println("給你點(diǎn)顏色看看..")color match {case x: String => println(x)case y: Int if y > 0 => println("大于0的整型")case Double => println("雙精度浮點(diǎn)型")case _ => throw new Exception("類型不匹配!")}}3.數(shù)組、元組匹配
def main(args: Array[String]): Unit = {val arr = Array(1, 2 ,3)arr match {case Array(1, x, y) => println(x)case Array(0) => println("0")// 1開頭的,后面任意case Array(1, _*) => println("0...")case _ => throw new Exception("類型不匹配!")}val lst = List(3, -1)lst match {case 0 :: Nil => println("only 0")case x :: y :: Nil => println(s"x: $x y: $y")case 0 :: tail => println("0 ...")case _ => println("something else")}val tup = (2, 3, 7)tup match {case (1, x, y) => println(s"1, $x , $y")case (_, z, 5) => println(z)case _ => println("else")}}4.樣例類
在Scala中樣例類是一中特殊的類,可用于模式匹配。
case class是多例的,后面要跟構(gòu)造參數(shù),case object是單例的
object ScalaDemo {def main(args: Array[String]): Unit = {val arr = Array(SubmitTask(1, "小強(qiáng)"), HeartBeat(1000), CheckTimeOutTask)arr(Random.nextInt(arr.length)) match {case SubmitTask(id, name) => println(s"$id,$name")case HeartBeat(t) => println(s"time:$t")case CheckTimeOutTask => println("CheckTimeOut!")}} }case class SubmitTask(id: Int, name: String) case class HeartBeat(time: Long) case object CheckTimeOutTask? 5.Option類型
在Scala中Option類型樣例類用來表示可能存在或也可能不存在的值(Option的子類有Some和None)。
Some包裝了某個值,None表示沒有值(和Java8類似)
Option[T] 是一個類型為 T 的可選值的容器: 如果值存在, Option[T] 就是一個 Some[T] ,如果不存在, Option[T] 就是對象 None 。
當(dāng)然,也可以使用getOrElse來控制默認(rèn)值
def main(args: Array[String]): Unit = {val myMap = Map("color" -> "blue")// get返回的就是一個option類型val v1: Option[String] = myMap.get("color")val v2: Option[String] = myMap.get("price")println(v1)// Some(blue)println(v2)// None}6.偏函數(shù)
被包在花括號內(nèi)沒有match的一組case語句是一個偏函數(shù),
它是PartialFunction[A, B]的一個實(shí)例,A代表參數(shù)類型,B代表返回類型,常用作輸入模式匹配
def func1: PartialFunction[String, Int] = {case "one" => 1case "two" => 2case _ => -1}后面調(diào)用的時(shí)候可以根據(jù)傳入的值進(jìn)行匹配,從而返回不同的值
更多基礎(chǔ)相關(guān),參考:https://www.cnblogs.com/wjcx-sqh/p/6551248.html
三、高階函數(shù)和隱式轉(zhuǎn)換
1.高階函數(shù)
Scala混合了面向?qū)ο蠛秃瘮?shù)式的特性,我們通常將可以做為參數(shù)傳遞到方法中的表達(dá)式叫做函數(shù)。
在函數(shù)式編程語言中,函數(shù)是“頭等公民”,高階函數(shù)包含:作為值的函數(shù)、匿名函數(shù)、閉包、柯里化等等。
作為值的函數(shù)
val fun = (x: Int) => x * 2 arr.map(fun)匿名函數(shù)
arr.map(x => x * 2) // 可以省略類型arr.map(_ * 2) // 可以使用神奇的下劃線代表當(dāng)前變量,更加簡潔!,也可以使用 m1 _來將方法轉(zhuǎn)換為函數(shù)
柯理化
柯里化指的是將原來接受兩個參數(shù)的方法變成新的接受一個參數(shù)的方法的過程
導(dǎo)言:
// 定義一個方法,不過形式上看起來有點(diǎn)像函數(shù) def m(x: Int) = (y:Int)=> x * y // 給它傳一個值,就變成了函數(shù) val fun = m(2) // fun = (y:Int) => 2 * y // 調(diào)用這個函數(shù) fun(5) //值為10 // 一步到位,就變成了 m(2)(5) // 這就得到了柯理化: def m(x:Int)(y:Int) = x * y//?可以只傳一個參數(shù):m(3)(_)
?
def main(args: Array[String]) {def f2(x: Int) = x * 2val f3 = (x: Int) => x * 3val f4: (Int) => Int = { x => x * 4 }val f4a: (Int) => Int = _ * 4val f5 = (_: Int) * 5val list = List(1, 2, 3, 4, 5)var new_list: List[Int] = null//第一種:最直觀的方式 (Int) => Int//new_list = list.map((x: Int) => x * 3)//第二種:由于map方法知道你會傳入一個類型為(Int) => Int的函數(shù),你可以簡寫//new_list = list.map((x) => x * 3)//第三種:對于只有一個參數(shù)的函數(shù),你可以省去參數(shù)外圍的()//new_list = list.map(x => x * 3)//第四種:(終極方式)如果參數(shù)在=>右側(cè)只出現(xiàn)一次,可以使用_new_list = list.map(_ * 3)new_list.foreach(println(_))var a = Array(1,2,3)a.map(_* 3)} 柯理化示例?
? 2.隱式轉(zhuǎn)換
簡單說,隱式轉(zhuǎn)換就是:當(dāng)Scala編譯器進(jìn)行類型匹配時(shí),如果找不到合適的候選,那么隱式轉(zhuǎn)化提供了另外一種途徑來告訴編譯器如何將當(dāng)前的類型轉(zhuǎn)換成預(yù)期類型。
通過隱式轉(zhuǎn)換,程序員可以在編寫Scala程序時(shí)故意漏掉一些信息,讓編譯器去嘗試在編譯期間自動推導(dǎo)出這些信息來。
隱式的對類的方法進(jìn)行增強(qiáng),豐富現(xiàn)有類庫的功能
那種以implicit關(guān)鍵字聲明的帶有單個參數(shù)的函數(shù)稱為隱式轉(zhuǎn)換函數(shù)
示例1:
?
import java.io.File import scala.io.Source//隱式的增強(qiáng)File類的方法 class RichFile(val from: File) {def read = Source.fromFile(from.getPath).mkString }object RichFile {//隱式轉(zhuǎn)換方法implicit def file2RichFile(from: File) = new RichFile(from)}object MainApp{def main(args: Array[String]): Unit = {//導(dǎo)入隱式轉(zhuǎn)換import RichFile._//import RichFile.file2RichFileprintln(new File("c://words.txt").read)} }?
示例2:
import java.awt.GridLayout/*** Created by ZX on 2015/11/13.*/ object ImplicitContext{//implicit def girl2Ordered(g : Girl) = new Ordered[Girl]{// override def compare(that: Girl): Int = if (g.faceValue > that.faceValue) 1 else -1//} implicit object OrderingGirl extends Ordering[Girl]{override def compare(x: Girl, y: Girl): Int = if (x.faceValue > y.faceValue) 1 else -1} }class Girl(var name: String, var faceValue: Double){override def toString: String = s"name : $name, faveValue : $faceValue" }//class MissRight[T <% Ordered[T]](f: T, s: T){ // def choose() = if(f > s) f else s //} //class MissRight[T](f: T, s: T){ // def choose()(implicit ord: T => Ordered[T]) = if (f > s) f else s //}class MissRight[T: Ordering](val f: T, val s: T){def choose()(implicit ord: Ordering[T]) = if(ord.gt(f, s)) f else s }object MissRight {def main(args: Array[String]) {import ImplicitContext.OrderingGirlval g1 = new Girl("yuihatano", 99)val g2 = new Girl("jzmb", 98)val mr = new MissRight(g1, g2)val result = mr.choose()println(result)} } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/jiangbei/p/8646922.html
總結(jié)
以上是生活随笔為你收集整理的大数据入门第二十天——scala入门(二)scala基础02的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信息系统十大管理
- 下一篇: SVN配置花生壳远程访问