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