25 scala 进阶

这篇博客深入探讨Scala的高级特性,包括高阶函数(如函数作为参数、匿名函数、闭包与柯里化)、类与对象的使用、对象的伴生类和伴生对象、Actor并发编程模型以及Akka框架在构建进程间通信中的应用。此外,还介绍了模式匹配、类型参数和隐式转换等核心概念。
摘要由CSDN通过智能技术生成

文章目录

scala 进阶

1.高阶函数

1.1 函数作为参数的函数

使用函数作为参数的方法,叫做高阶函数

package cn.itcast.scala

object ScalaTest {
   


  val myFunc = (x:Int) => {
   x*x}
  def main(args: Array[String]): Unit = {
   
    //方法就是函数,函数就是对象
    def myMethod(x:Int) : Int = {
   x*x}

    val myArray0 = Array(1,3,5,7,9).map(x => x*x)   //匿名函数优先使用
    val myArray1 = Array(1,3,5,7,9).map(myFunc)     //函数就是对象
    val myArray2 = Array(1,3,5,7,9).map(myMethod)   //方法就是函数
    val myArray3 = Array(1,3,5,7,9).map(_*2)        //实现不了x*x功能 因为x出现了两次,不能使用_
    println(myArray0.mkString(","))
    println(myArray1.mkString(","))
    println(myArray2.mkString(","))
    println(myArray3.mkString(","))
  }

}

1.2 匿名函数

package cn.itcast.scala

object ScalaTest {
   
  def main(args: Array[String]): Unit = {
   
    println((x:Int,y:Int) => {
   x * y})   // <function2>
  }
}

1.3 高阶函数

package cn.itcast.scala

object ScalaTest {
   


  def main(args: Array[String]): Unit = {
   
    val func3: (String, Int) => (Int, String) = {
   
      (x, y) => (y + 2, x + "hello")
    }

                    //函数匿名函数定义第二种方式
    def myMethod3(hello: (String, Int) => (Int, String)): Int = {
   
      val result: (Int, String) = hello("zhangsan", 60)
      result._1
    }

    val result: Int = myMethod3(func3)
    println(result)   //62
  }
}

1.4 高阶函数作为方法的返回类型

package cn.itcast.scala

object ScalaTest {
   


  def main(args: Array[String]): Unit = {
   
    def myFunc4(x:Int) = {
   
      //方法的最后返回值,是一个匿名函数
      (y:String) =>y + x
    }
    println(myFunc4(50))	//<function1>
  }
}

1.5 参数类型推断

package cn.itcast.scala

object ScalaTest {
   


  def main(args: Array[String]): Unit = {
   
    val myArray = Array(1, 3, 5, 7, 9)
    //map当中需要传入一个函数,我们可以直接定义一个函数
    println(myArray.map((x: Int) => x * 2).mkString("==="))
    //进一步化简 参数推断省去类型信息
    println(myArray.map((x) => x * 2).mkString("==="))
    //进一步化简  单个参数可以省去括号
    println(myArray.map(x => x * 2).mkString("==="))
    ///进一步化简  如果变量只在=>右边只出现一次,可以用_来代替
    println(myArray.map(_ * 2).mkString("==="))
    /*
    2===6===10===14===18
	2===6===10===14===18
	2===6===10===14===18
	2===6===10===14===18
    *\
  }
}

1.6 闭包与柯里化

package cn.itcast.scala

object ScalaTest {
   


  def main(args: Array[String]): Unit = {
   
    //柯里化 柯里化定义形式
    def kery(x:Int)(y:Int) = {
   
      x+y
    }

    val kery1: Int = kery(30)(20)
    println(kery1)

    val keryResult = (x:Int) => {
    (y:Int) => {
   x + y} } // 函数的返回值也是函数,为function1,切内部是匿名函数无法赋值
    println(keryResult(10))
                     //keryResult(20) => 匿名函数  y:Int => 20+y <=1,3,5,7,9
    val myArray = Array(1,3,5,7,9).map(keryResult(20))
    println(myArray.toBuffer) //ArrayBuffer(21, 23, 25, 27, 29)

    //柯里化推导过程
    //柯里化守门Scala面向函数式编程,必然导致的一种结果
    def keryMethod(x:Int) = {
   
      //里面的函数,将外面的参数包起来了,叫做闭包
      y:Int => {
   y + x}
    }
    keryMethod(30)
    
  }
}

总结:
函数可以用来干嘛 ==>
1.作为一个方法的参数
2.函数可以直接调用
3.匿名函数无法调用,但是可以通过作为一个方法的参数进行赋值调用如

Array(1,3,5,7,9).map(keryResult(20))

2.scala当中的类

2.1 类的定义与创建

package cn.itcast.scala

class Person {
   
  //定义一个属性,叫做name的,使用val不可变量来进行修饰
  // 用val修饰的变量是可读属性,有getter但没有setter(相当与Java中用final修饰的变量)自动生成该方法
  val name:String ="zhangsan"
  //定义一个属性,叫做age的,使用var可变量来进行修饰
  //用var修饰的变量都既有getter,又有setter 自动生成该方法
  var age:Int = 28

  //类私有字段,只能在类的内部使用或者伴生对象中访问
  private val  address:String = "地球上"

  //类私有字段,访问权限更加严格的,该字段在当前类中被访问
  //在伴生对象里面也不可以访问
  private[this] var pet = "小强"

  //在类当中定义了一个方法,
  def hello(first:Int,second:String):Int ={
   
    println(first+"\t"+second)
    250
  }
  /**
   * 定义了一个函数
   */
  val func1 =(x:Int,y:Int) =>{
   
    x+y
  }
}

2.2 类的实例化以及使用

package cn.itcast.scala

object ScalaClass {
   
  def main(args: Array[String]): Unit = {
   
    val person = new Person
    val name: String = person.name
    val age: Int = person.age
    println(name)
    println(age)
    
    person.age = (30) // 这个是赋值操作
    person.age= (30)  // age= 这个是set方法,.age=连起来写
    person.age_= (80) // age_= 这个是set方法
    println(person.age) //这个是get方法
    //调用函数或者方法
    val hello: Int = person.hello(120,"zhangsan")
    println(hello)  //250
  }

}

2.3 属性的getter和setter方法

对于scala类中的每一个属性,编译后,会有一个私有的字段和相应的getter、setter方法生成

//getter方法
println(person age)
//setter方法
println(person age_= (18))
//getter方法
println(person.age)

当然了,你也可以不使用自动生成的方式,自己定义getter和setter方法

class Dog2 {
  private var _leg = 4
  def leg = _leg
  def leg_=(newLeg: Int) {
    _leg = newLeg
  }
}
使用之:
val dog2 = new Dog2
dog2.leg_=(10)
println(dog2.leg)

规范提示:自己手动创建变量的getter和setter方法需要遵循以下原则:

1) 字段属性名以“_”作为前缀,如:_leg
2) getter方法定义为:def leg = _leg
3) setter方法定义时,方法名为属性名去掉前缀,并加上后缀,后缀是:“leg_=”,如例子所示

2.4 类的构造器

scala当中类的构造器分为两种:主构造器和辅助构造器
主构造器,写在类名后面的。
所有的辅助构造器,在最后都必须调用另外一个构造器

java中构造器

public  class Dog{
   
 public Dog(String name,int age){
   
 	System.out.println("xxxx")
 }
}
new Dog("小黑"3)

scala中构造器

package cn.itcast.scala

/**
 * 顶一个class类,主构造器带有两个参数,name与age
 *
 * @param name
 * @param age
 *            scala的执行代码,可以直接将代码写在class当中,而在java当中不能
 *            在Scala编译之后成为.class文件
 *            将我们所有class类的代码都进入到了主构造器方法当中去了
 *            class Dog{
 *              public Dog(String name,int age){
 *                println(name)
 *                println(age)
 *              }
 *            }
 */
class Dog(name: String, age: Int) {
   

  println(name)
  println(age)

  var gender: String = "";

  //使用this关键字来定义我们的构造器
  def this(name: String, age: Int, gender: String) {
   
    //每个辅助构造器,都必须以其他辅助构造器,或者主构造器的调用作为第一句
    this(name: String, age: Int)
    this.gender = gender
  }

  var color = "";

  /**
   * 我们也可以通过private来进行修饰我们的构造器,
   *
   * @param name
   * @param age
   * @param color
   * @param gender
   */
  private def this(name: String, age: Int, color: String, gender: String) {
   
    this(name: String, age: Int)
    this.color = color
  }

}

两个构造器之间不能相互调用
Object通过构造器生成对象

package cn.itcast.scala

object ScalaClass {
   
  def main(args: Array[String]): Unit = {
   
    val xiaoheigou: Dog = new Dog("xiaoheigou",3)
    val xiaobaigou: Dog = new Dog("xiaobaigou",2,"cixing")
  }
}

3.scala当中的对象

Java中

public  class MyClass{

   public static String name="xxx"

   public String age = "xxx"

   public static String getMyAge(){
	return "xxx"
   }

   public int getMyRealAge(){
   
   return 1;
   }
}

Scala中

将static和非static的东西全部分开
object 里面装的东西,可以简单的认为,全部都是static修饰的
class里面装的东西,可以简单的任务,全部都是没有static修饰的(需要new对象)

3.1 scala当中的Object

定义一个class类,然后在class类当中定义一个Object的对象。object对象当中的所有属性或者方法都是静态的

class Session {
   
  def hello(first:Int):Int={
   
    println(first)
    first
  }
}
object SessionFactory{
   
  val session = new Session
  def getSession():Session ={
   
    session
  }
  def main(args: Array[String]): Unit = {
   

    for(x <- 1 to 10){
   
      //通过直接调用,产生的对象都是单列的
      val session = SessionFactory.getSession()
      println(session)
    }
  }
}

3.2 伴生类与伴生对象

在这里插入图片描述
特点:

1.如果有一个class文件,还有一个与class同名的object文件,那么就称这个object是class的伴生对象,
class是object的伴生类;
2.伴生类和伴生对象必须存放在一个.scala文件中;
3.伴生类和伴生对象的最大特点是,可以相互访问;
package cn.itcast.scala

class ClassObject {
   
  val id = 1
  private var name = "itcast"
  def printName(): Unit ={
   
    //在Dog类中可以访问伴生对象Dog的私有属性
    println(ClassObject.CONSTANT + name )
  }
}

object ClassObject{
   
  //伴生对象中的私有属性
  private val CONSTANT = "汪汪汪 : "
  def main(args: Array[String]) {
   
    val p = new ClassObject
    //访问私有的字段name
    p.name = "123"
    p.printName()
  }
}

3.3 scala当中的apply方法

通过apply方法来创建我们的伴生类,可以通过伴生对象来创建我们的伴生类,更加简洁和方便

package cn.itcast.scala

//定义一个class类,主构造器传入一个参数
class ApplyClassObject(name:String) {
   
  println(name)

}

object ApplyClassObject{
   
  def apply(name: String): ApplyClassObject = new ApplyClassObject(name)

  def main(args: Array[String]): Unit = {
   
    val applyClassObject1 = new ApplyClassObject("张三")
    //通过伴生对象,直接调用调用apply方法,来获取我们的一个伴生类
    val applyClassObject2 = ApplyClassObject("lisi")

    //底层还是调用了apply方法,apply还是new Array[Int](5)
    val myArray = Array(1,2,3,4,5)
    val  myArray2 = new Array[Int](10)
    myArray2(0)=1
    myArray2(1)=2

  }
}

3.4 scala当中的main方法

//1.在object中定义main方法
object Main_Demo1 {
   
  def main(args: Array[String]) {
   
    if(args.length > 0){
   
      println("Hello, " + args(0))
    }else{
   
      println("Hello World1!")
    }
  }
}
//2.使用继承App Trait ,将需要写在 main 方法中运行的代码
// 直接作为 object 的 constructor 代码即可,
// 而且还可以使用 args 接收传入的参数。

object Main_Demo2 extends App{
   
  if(args.length > 0){
   
    println("Hello, " + args(0))
  }else{
   
    println("Hello World2!")
  }
}

3.5 枚举

java

public enum{
HELLO,ABC,123
}


enum.HELLO

public  static  String CONSTANTS = "HELLO"

Scala中没有枚举类型,但是我们可以通过定义一个扩展Enumeration类的对象,并以value调用初始化枚举中的所有可能值:

4.scala当中的继 承

4.1 Scala中继承(extends)的概念

在这里插入图片描述

在这里插入图片描述

ackage cn.itcast.extends_demo

class Person {
   
  val name="super"
  def getName=this.name
}
class Student extends Person{
   
  //继承加上关键字
  override
  val name="sub"
  
  //重写方法
  override def getName = "xxx"		
	
  //子类可以定义自己的field和method
  val score="A"
  def getScore=this.score
}

4.2 Scala中override 和 super 关键字

在这里插入图片描述

class Person1 {
   
  private val name = "leo"
  val age=50
  def getName = this.name
}
class Student1 extends Person1{
   
  private val score = "A"
  //子类可以覆盖父类的 val field,使用override关键字
  override
  val age=30
  def getScore = this.score
  //覆盖父类非抽象方法,必须要使用 override 关键字
  //同时调用父类的方法,使用super关键字
  override def getName = "your name is " + super.getName
}

4.3 Scala中isInstanceOf 和 asInstanceOf

Class B  extends Class  A
Class C 

 B instanceOf  A   => 如果判断 B是A的子类  (A)B


 C instanceOf  A  ==> 如果判断 C不是A的子类  不能强转

java当中只提供了子类判断是否属于父类形 instanceOf,没有提供判断一个类是否是另外一个类的父类的方法

isInstanceOf 和 asInstanceOf
isInstanceOf    ==>  类似于java当中的instanceOf  做类型判断的
如果  判断 A   isInstanceOf  B  为true
可以调用  A  asInstanceOf  B 做类型转换
asInstanceOf    ==>  做类型转换的

在这里插入图片描述

package cn.itcast.extends_demo

class Person3 {
   }
class Student3 extends Person3
object Student3{
   
    def main (args: Array[String] ) {
   
    val p: Person3 = new Student3
    var s: Student3 = null
    //如果对象是 null,则 isInstanceOf 一定返回 false
    println (s.isInstanceOf[Student3])
    // 判断 p 是否为 Student3 对象的实例
  if (p.isInstanceOf[Student3] ) {
   
    //把 p 转换成 Student3 对象的实例
      s = p.asInstanceOf[Student3]
  }
  println (s.isInstanceOf[Student3] )
  }
}

4.4 Scala中getClass 和 classOf

传入一个Any 是不是Array 这一个确定的类型

package cn.itcast.extends_demo

class Person4 {
   }
class Student4 extends Person4
object Student4{
   
  def main(args: Array[String]) {
   <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值