scala (二)

mac2025-01-08  36

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
最新回复(0)