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