scala(偏函数、部分函数、模式匹配、面向对象oop)
一、偏函数
偏函数是只对函数定义域的一个子集进行定义的函数
PartialFunction[-A,+B]是一个特质
A为函数定义域,B为偏函数返回值类型
apply()
isDefinedAt()
偏函数,传入一个String,返回一个Int
def funPartiton: PartialFunction[String, Int] = {
case "helle" => 1
case "world" => 0
case _ => 3
}
val i = funPartiton("kb11")
println(i)
def funPart2:PartialFunction[Int,String]={
case 1=>"优秀"
case 2=>"良好"
case 3=>"合格"
case _=>"渣渣"
}
println(funPart2(4))
val arr = Array(1,2,3,4)
val strings = arr.collect(funPart2)
def fun3:PartialFunction[String,Any]={
case "man" => 1
case "wowan" => 0
case _=> "不合法输入"
}
val arrs = Array("man","wowan","ww")
arrs.collect(fun3).foreach(println)
二、部分函数
def showMsg(title: String, content: String, height: Double) = {
println(title + " " + content + " " + height)
}
常规调用方法:
showMsg("警告", "当前河床水位线:", 19.8)
部分函数:
val title:String = "警告"
def showAlarm = showMsg(title,_:String,_:Double)
showAlarm("部分函数 当前河床水位线:", 19.8)
val content:String = "部分函数2 当前河床水位线:"
def showAlarm2 = showMsg(title,content,_:Double)
showAlarm2(19.8)
三、模式匹配
(1)基本模式匹配
def match1(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
def fun(x:Any): Unit = {
x match {
case x : Int => println("int型")
case x : String => println("string型")
case x : Double => println("Double型")
}
}
println(fun(10))
println(fun(3.5))
(2)模式守卫(在模式后加if)
def match2(x:Int):String=x match {
case 1 => "one"
case 2 => "two"
case _ if x > 9 && x < 100 => "两位数"
case _ => "other"
}
println(match2(2))
println(match2(22))
println(match2(8))
//输出
//two
//两位数
//other
(3)匹配异常
def match5(e: Exception) = {
e match {
case e1: IndexOutOfBoundsException => println("IndexOutOfBoundsException")
case e2: NullPointerException => println("NullPointerException")
case _: Exception => println("Exception")
}
}
(4)匹配字符串
def match6(arr: Array[String]): Unit = {
arr match {
case Array("KB11") => println("Hello kb11")
case Array(str1,str2)=>println(str1,str2)
case Array("KB12",_*)=> println("多个班级")
case Array(_,_,"bb",_*) => println(arr(0),arr(1),"bb")
case _ => println("who are you")
}
}
测试:
match6(Array("a","b","bb","kb"))
四、Scala面向对象
(1)类 (class)
//主构造器的参数列表直接定义在类名后面
//主构造器执行类定义汇总的搜有哦语句
class Student {//无参的主构造器
//定义成员变量
var name="zhang"
var age:Int=_ //0
var gender:String=_ //null
//辅助构造器可以调用主构造器,也可以调用其他辅助构造器
//定义一个辅助构造器1
def this(name:String,age:Int)={
//辅助构造器必须要从调用其它构造器开始
this()
this.name=name
this.age=age
}
//定义一个辅助构造器2
def this(gender:String)={
this("lisi",18)//调用辅助构造器1
this.gender=gender
}
//定义一个成员方法
def study()={
println("good good study,day day up")
}
}
//调用需要写在main方法里,main方法需要定义到object中
//测试
object Test01{
def main(args: Array[String]): Unit = {
//new一个对象出来后,可以使用成员变量和成员方法
//使用主构造器创建对象
val stu1 = new Student()
println(stu1.name)
println(stu1.age)
println(stu1.gender)
stu1.study()
//使用辅助构造器创建对象
val stu2 = new Student("zhangsan",20)
println(stu2.name)
println(stu2.age)
println(stu2.gender)
stu2.study()
stu2.age=25//可以自动生成get和set方法,可以对变量进行修改,需要是var定义的变量
val stu3=new Student("女")
println(stu3.name)
println(stu3.age)
println(stu3.gender)
stu3.study()
}
}
//输出
zhang
0
null
good good study,day day up
zhangsan
20
null
good good study,day day up
lisi
18
女
good good study,day day up
(2)抽象类 (abstract class) 和 特质(trait)
抽象类可包含未实现的方法,即抽象方法,无方法体
抽象类无法实例化
抽象类使用“abstract”关键字修饰
子类重写父类抽象方法时,“override”关键字可选
子类重写父类非抽象方法,“override”关键字必写
Scala中没有接口(interface)的概念
特质用于在类之间共享程序接口和字段,类似Java接口
特质是字段和方法的集合,可以提供字段和方法实现
类和单例对象都可以扩展特质(extends)
特质不能被实例化,因此没有构造参数,类似Java接口
特质使用“trait”关键字定义
实现特质中的方法使用“override”
abstract class Car {
def brand: String
def engine: String
def laba() :Unit={
println("鸣笛")
}
}
trait Type1{
def wheele:String={
"四个轮子"
}
}
trait Type2{
def fly():Unit={
println("飞上天空")
}
def downSea():Unit
}
trait balance{
def balance : String={
"平衡"
}
}
trait price{
def cost:Unit
}
class BMW extends Car with Type2 {
override def brand: String = {
println("BMW X6")
return "BMW X6"
}
override def engine: String = {
println("3.0T")
return "3.0T"
}
override def downSea(): Unit = {
println("不能下海")
}
}
class LinYun extends Car with Type2 {
override def brand: String = {
println("凌云骑车")
"凌云骑车"
}
override def engine: String ={
println("4.0")
"4.0"
}
override def downSea(): Unit = {
println("不能下海")
}
}
object CarTest {
def main(args: Array[String]): Unit = {
// val bmw = new BMW
// bmw.brand
// bmw.engine
// bmw.laba()
// println(bmw.wheele)
// bmw.downSea()
// bmw.fly()
//创建类实例时可以直接使用with+子特质来实现子特质中的方法
val linYun:LinYun with Type1 with Type2 with balance= new LinYun with Type1 with Type2 with balance {
override def balance: String = {
println("两轮,平衡汽车")
"两轮,平衡汽车"
}
}
linYun.fly()
linYun.downSea()
linYun.engine
linYun.balance
//创建类实例时可以直接使用with+子特质来实现子特质中的方法
**val bmw:BMW with Type1 with Type2 with price= new BMW with Type1 with Type2 with price {
override def cost: Unit= {
println("200万")
}
}
bmw.cost**
}
}
通过这种方式创建对象,可以直接在new的后面用with的方式加入特质,并且用内部类的方式重写特质中的方法
(3)单例对象(object) —伴生类 伴生对象
Scala的类中无法定义静态成员,即无static关键字。如何像Java一样表达类的静态成员变量、成员方法与静态代码块?
Scala解决方案:单例对象
使用“object”关键字声明,可包含变量、方法与代码定义
单例对象中的成员变量、成员方法通过单例对象名直接调用
单例对象第一次被访问时初始化,并执行全部代码块
单例对象不能new,且无构造参数
程序入口main()方法必须定义在单例对象中
单例对象与同名类定义在同一文件中时形成绑定关系
伴生(Companion)
单例对象与同名类定义在同一文件中时形成绑定关系
同名类称为单例对象的伴生类(class)
单例对象称为同名类伴生对象(object)
伴生类与伴生对象可相互访问各自私有成员
伴生对象可为伴生类增加静态成员
/*
伴生类 伴生对象
*/
class Oop1(name:String,age:Int){ //scala默认构造函数:主构造
println("-----------oop1 class one---------")
println(name + age)
var uname:String=name
val uage:Int=age
var uaddress:String=""
def this(name:String){
this(name,1)
println("oop1 构造方法")
}
def this(){
this("ysm",23)
}
def this(name:String,age:Int,address:String){
this(name,age)
uaddress= address
}
//类中可以直接访问object中的属性
def showInfo() = {
println("进入class oop1 中的showInfo方法")
println("访问object oop1 中的showInfo方法")
println("结束访问object oop1 中的showInfo方法")
println("name:" + name + " age:" + age + " address:" + Oop1.country)
}
println("-----------oop1 class two---------")
}
object Oop1 {
val country:String="中国"
def apply(name:String,age:Int): Oop1 = new Oop1(name,age)
def apply(name:String,age:Int,address:String): Oop1 = new Oop1(name,age,address)
def main(args: Array[String]): Unit = {
val op1 = Oop1("ysm",23)
val op2 = Oop1("ysm",23,"安德门")
println(op1.showInfo())
println(op2.showInfo())
println("-----------oop1 object one---------")
def showInfo():Unit={
println("-----------oop1 object three---------")
println("this is oop1 object")
}
println("-----------oop1 object two---------")
}
}
(4)样例类(case class)
一个类可以作为另一个类的成员,称为内部类
Java内部类是外部类的成员
Scala内部类绑定到外部类的对象实例
创建样例类无需new关键字
样例类构造参数默认声明为“val”,自动实现类构造参数的getter
样例类构造参数声明为“var”时,自动实现类构造参数的setter和getter
样例类自动创建伴生对象
样例类自动实现的其他方法
toString()、equals()、copy()、hashCode()
伴生对象中的apply()、unapply()
case class Teacher(name: String, age: Int)
def match3(teacher: Teacher) = {
teacher match {
case Teacher("gree", 37) => println("hello gree teacher")
case Teacher("kb11", 6) => println("hello kb11")
case x: Teacher => println("hello" + x.name)
}
}
def match7(teacher: Teacher)={
teacher match {
case Teacher(_,21) => println("姓名:"+teacher.name)
}
}
//样例类例2:
class Person
case class Teacher2(name:String,age:Int) extends Person
case class Worker2(name:String,age:Int) extends Person
case class Student2(name:String,age:Int) extends Person
def match8(person: Person):Unit={
person match {
case Teacher2(name,21)=> println(name)
case Worker2(name,age) if name=="repairWorker" => println("修理工" + age)
case person1:Student2 if person1.name=="小学生" => println("花朵")
case _=> println("不知道是啥")
}
}
//样例类例2:
case class Word(degree: String)
def match4(word: Word) = {
word match {
case Word("A") => println("优秀")
case Word("B") => println("良好")
case Word("C") => println("合格")
case x: Word => println(x.degree + "不合格")
}
}
def main(args: Array[String]): Unit = {
// match7(Teacher("yyy",21))
// match3(Teacher("gree", 37))
// match4(Word("E"))
}