Scala详解(3)

这篇具有很好参考价值的文章主要介绍了Scala详解(3)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Scala

函数

柯里化(Currying)

  1. 柯里化指的是将多个参数的函数变成接收单一参数的过程

  2. 案例

    package com.fesco.method
    ​
    object MethodDemo1 {
    ​
      def main(args: Array[String]): Unit = {
    ​
        // 定义一个函数:获取两个数字中较大的那个数字
        // 基本函数
        /*
        def max(a: Int, b: Int): Int = if (a > b) a else b
        println(max(3, 5))
         */
        // 高阶函数
        def max(a: Int) = {
          def m(b: Int): Int = if (a > b) a else b
    ​
          m _
        }
    ​
        val r = max(4)
        println(r(2))
        println(r(1))
        println(max(5)(7))
    ​
        // max中直接嵌套了一个m函数,所有的计算逻辑都是在m函数中完成,之后直接将m函数返回
        // 这个过程称之为柯里化
        def maxCurry(a: Int)(b: Int) = if (a > b) a else b
    ​
        println(maxCurry(4)(3))
        // 柯里化虽然将闭包的过程进行了简化,但是导致调用的时候必须将参数全部传入
        val mc = maxCurry(3)(5)
        println(mc)
      }
    ​
    }
  3. 柯里化本质上还是闭包!!!

传名参数

  1. 案例

    package com.fesco.method
    ​
    object MethodDemo2 {
    ​
      def main(args: Array[String]): Unit = {
    ​
        // 定义一个函数,需要接收一个参数,参数的结果导向只要是Int就可以
        // 接收的是一段逻辑,只要这段逻辑的结果是Int就可以
        // f的数据类型是 =>Int,也就意味着,是要逻辑的结果是Int类型就可以
        def twice(f: => Int): Unit = println(f)
    ​
        twice(3)
        twice(if (3 > 5) 3 else 5)
    ​
        def add(x: Int, y: Int): Int = x + y
    ​
        twice(add(3, 5))
    ​
        // 要求传入的必须是(Int, Int) => Int的函数
        def calc(f: (Int, Int) => Int): Unit = println(f)
        calc(add)
    ​
    ​
      }
    ​
    }
  2. 案例

    package com.fesco.method
    ​
    object MethodDemo3 {
    ​
      def main(args: Array[String]): Unit = {
    ​
        // 打印1-10
        var i = 1
        while (i <= 10) {
          println(i)
          i += 1
        }
    ​
        println("=" * 50)
    ​
        // 会发现,对于while循环,可以拆分成两部分
        // 1. 条件 - 在定义while结构的时候,并不知道条件是什么,而是用户在使用的时候来传入。
        //    对于开发人员而言,只需要确定一件事就可以:条件的结果一定是一个Boolean型
        // 2. 执行逻辑 - 在定义while结构的时候,需要执行什么逻辑,开发人员不知道
        //
        def whileLoop(condition: => Boolean)(body: => Unit): Unit = {
          // 判断条件是否成立
          if (condition) {
            // 只要条件成立,那么就执行逻辑
            body
            whileLoop(condition)(body)
          }
        }
    ​
        var n = 1
        // 如果({}),那么()可以省略
        /*
        whileLoop(n <= 10)({
          println(n)
          n += 1
        })
         */
        whileLoop(n <= 10) {
          println(n)
          n += 1
        }
      }
    ​
    }

懒加载

  1. 在函数的返回值之前用lazy来修饰,这个函数就会被推迟执行,直到结果被使用的时候,函数才会执行,这个过程就称之为懒加载,或者惰性加载

    package com.fesco.method
    ​
    object LazyDemo {
    ​
      def main(args: Array[String]): Unit = {
    ​
        def minus(a: Int, b: Int): Int = {
          println("running")
          a - b
        }
    ​
        val m1 = minus(6, 3)
        println("=" * 50)
        // minus函数不执行
        lazy val m2 = minus(7, 2)
        // 打印m2 ===> m2被使用
        // 加载执行minus函数
        println(m2)
    ​
      }
    ​
    }
  2. 注意:lazy只能修饰val不能修饰var

面向对象

类和对象

  1. 在Scala中,通过class来定义类

    package com.fesco.objectx
    ​
    object PersonDemo {
    ​
      def main(args: Array[String]): Unit = {
    ​
        val p = new Person
        p.setName("Amy")
        p setAge 15
    ​
        println(p.getName)
        println(p.getAge)
        println(p.id)
    ​
      }
    ​
    }
    ​
    // 通过class定义类
    class Person {
    ​
      // 属性
      // 在Scala中,不支持先声明后给值
      // _表示给这个属性默认值
      var name: String = _
      var age: Int = _
      // 常量必须给值,不能使用默认值
      val id:String = "xxx"
    ​
      // 方法
      def setName(name: String): Unit = this.name = name
    ​
      def getName = this.name
    ​
      def setAge(age: Int) = this.age = age
    ​
      def getAge = this.age
    ​
    }
  2. 如果类中没有属性和函数,那么这个类在定义的时候可以省略{}不写

    class Driver
  3. 在Scala中,所有的类默认都是公共的,不需要使用public来修饰。一个scala文件中可以包含多个类

构造器

  1. 在Scala中,没有构造函数的说法,取而代之的是构造器。Scala中,构造器可以定义多个,分为主构造器和辅构造器

  2. 主构造器的结构

    class 类名(参数列表){ // 主构造器
        类体
    }
  3. 如果不指定,那么主构造器默认是无参的

    // 默认无参
    class Person() {}
    // 含参构造
    class Student(var name:String){}
  4. 如果需要提供新的构造方式,那么需要通过辅构造器来完成

    class 类名(参数列表){ // 主构造器
        def this(参数列表){} // 辅构造器
    }
  5. 辅构造器可以有多个

  6. 辅构造器中不能定义类的属性!!!

  7. 辅构造器中第一行必须先调用主构造器

    package com.fesco.objectx
    ​
    object StudentDemo {
    ​
      def main(args: Array[String]): Unit = {
    ​
        val s = new Student("David", 15, "fesco")
        println(s.name)
        println(s.school)
        // age不认为是属性,所以s.age是错误的
        s.info()
        val s2 = new Student("Bob", 10, 3)
        println(s2.grade)
      }
    ​
    }
    ​
    // 主构造器
    // var和val定义的参数,默认会编译成这个类的属性
    // 没有var和val定义的参数,就是普通变量
    class Student(var name: String, age: Int, val school: String) {
    ​
      var grade: Int = _
    ​
      def this(name: String, age: Int, grade: Int) {
        // 辅构造器中第一行必须先调用主构造器,或者调用其他的辅构造器
        this(name, age, "fesco")
        this.grade = grade
      }
    ​
      def info(): Unit = println(s"name:${this.name}, age:$age, school:${this.school}")
    }

权限控制

  1. 在Scala中一共有三种权限:公共、protectedprivate

  2. 如果类、属性或者方法之前没有写其他的权限修饰符,那么默认就是公共权限,因此Scala中没有public关键字

  3. private和Java一样,修饰的属性和方法只能在本类中使用

  4. Scala中的protected比Java中更严格,只能在本类中和子类中使用,同包类和其他类中不能使用

  5. 案例

    package com.fesco.objectx
    ​
    object ControlDemo {
    ​
    }
    ​
    // 职业
    class Profession {
    ​
      // 没有限定就是公共的
      val id: Long = 12865496L
      // 只能在本类和子类中使用
      protected var department: String = _
      // 只能在本类中使用
      private var name: String = _
      // 限定包的范围 - private[包名]
      private[objectx] var address: String = _
    ​
    }
    ​
    class Teacher extends Profession {
    ​
      def info(): Unit = println(s"$id, $department")
    ​
    }
  6. 案例

    package com.fesco.objectx
    ​
    object RectangleDemo {
    ​
      def main(args: Array[String]): Unit = {
    ​
        val r = new Rectangle
        r.height = 5.2
        println(r.height)
        r.width = 4.5
        println(r.width)
        println(r.area)
    ​
      }
    ​
    }
    ​
    class Rectangle {
    ​
      // 在Scala中,推荐属性使用_开头,和方法做区分
      private var _height: Double = _
      private var _width: Double = _
    ​
      /*
      def setHeight(height: Double): Unit = this._height = height
      def getHeight: Double = this._height
       */
      def height: Double = _height
    ​
      def height_=(height: Double): Unit = this._height = height
    ​
      def width: Double = _width
    ​
      def width_=(width: Double): Unit = this._width = width
    ​
      def area: Double = this._height * this._width
    ​
    }

定义
  1. 在Scala中,依然是通过package来定义包

    package 包名
    // 例如
    package com.fesco
  2. 注意:在Java中,一个.java文件中只能有一个package语句;在Scala中,允许定义多个package语句,根据定义顺序,后定义的包是前边包的子包

    // 方式一:
    package com.fesco.pa
    // 方式二
    package com
    package fesco
    package pa
    // 方式三
    package com.fesco
    package pa
    // 方式四
    package com
    package fesco.pa
  3. 为了表示层级关系,还提供了嵌套风格

    package com {
        package fesco {
            package pa{}
        }
    }
  4. 注意:在Java中,package语句需要放在.java文件的第一行,Scala中不做要求

    // 如果父包和子包之间没有其他代码,那么不需要写{}
    package com
    package fesco
    // 如果父包和子包之间有其他的代码,那么子包需要写{}
    package com
    class Student{} // Student的全路径名是com.Student
    // fesco是com的子包
    package fesco {
        class Pupil{} // Pupil的全路径名是com.fesco.Pupil
    }
    // test是com的子包
    package test {
        class Junior{} // Junior的全路径名是com.test.Junior
    }
导包
  1. 在Scala中,依然是通过import来导入包,但是Scala中,导包语句可以书写在任何地方

    object PackageDemo2 {
    
      def main(args: Array[String]): Unit = {
    
        // 导包语句可以定义在任何位置
        import java.util.ArrayList
        val list = new ArrayList[String]()
    
      }
    
    }
  2. 导包的时候,用_表示通配符

    // 导入util包下的所有的类但是不包含子包的类
    import java.util._
    // 导入Collections类中的所有属性和函数
    import java.util.Collections._
  3. 如果导入同一个包下的多个类,可以使用{}将类放到同一行上

    import java.util.{List, ArrayList, Map}
  4. Scala中,还允许在导包的时候给类来起别名

    import scala.collection.mutable.{Map => MulMap}
    import scala.collection.immutable.{Map => ImMap}
    // 导入java.util包下的所有的类,同时将ArrayList的别名定义为AL
    import java.util.{ArrayList => AL, _}
    // 可以利用这个方式来屏蔽类
    // 表示禁止使用HashMap类
    import java.util.{HashMap => _}
    // 导入java.util包下除了HashMap以外的类
    import java.util.{HashMap => _, _}
  5. _root_表示根目录

  6. Scala中,默认导入了三个包中的类:java.lang包,scala包,scala.Predef

包对象(package object)
  1. 在Scala中,可以为每一个包来定义一个同名对象,称之为包对象package object

  2. 包对象必须和包同名,所以每一个包只能有1个包对象

  3. 在包对象中,可以定义属性和方法。在同一个包中的所有的类都可以访问同名包对象中的函数和属性

    package com.fesco.objectx
    package test
    
    object PackageDemo {
    
      def main(args: Array[String]): Unit = {
    
        println(test.add(3, 7))
        println(test.id)
        
      }
    
    }
    
    package object test {
    
      val id = 5846
    
      def add(x: Int, y: Int): Int = x + y
    
    }
  4. 在Scala中,可以将这个包中所有的类共享的属性或者函数定义到包对象中

面向对象的特征

  1. 面向对象的特征:封装、继承、多态。Scala作为一门完全面向对象的语言,一定是符合三大特征

  2. 封装:Scala中,提供了对象的封装和函数的封装

  3. 继承:Scala也是通过extends关键字来完成继承。同样,Scala支持类和类之间的单继承而不是多继承,子类同样可以通过继承来使用父类中的部分方法或者属性

  4. 多态:包含了对象的多态(向上造型)和行为的多态(方法的重载和重写)

  5. 向上造型:父类声明,子类实现

    package com.fesco.dt
    
    object ExtendsDemo {
    
      def main(args: Array[String]): Unit = {
    
        val s: Student = new Pupil
    
      }
    
    }
    
    class Student
    
    class Pupil extends Student
  6. 方法的重写:子类继承父类之后,可以覆盖/重写父类中的方法。在Scala中,需要通过override关键字来明确定义这个函数是重写的

    package com.fesco.dt
    
    object ExtendsDemo {
    
      def main(args: Array[String]): Unit = {
    
        val s: Student = new Pupil
        s.study()
    
      }
    
    }
    
    class Student {
      def study(): Unit = println("studying")
    }
    
    class Pupil extends Student {
      // 明确的使用override来定义
      override def study(): Unit = println("the pupil is studying")
    }
  7. 在Scala中,还支持属性的重写。如果父子类中存在同名属性,且该属性用val来定义,那么可以进行属性的重写

    package com.fesco.dt
    
    object ExtendsDemo {
    
      def main(args: Array[String]): Unit = {
    
        val s: Student = new Pupil
        s.study()
        println(s.versionUID)
    
      }
    
    }
    
    class Student {
    
      val versionUID: Long = 54896524L
    
      def study(): Unit = println("studying")
    }
    
    class Pupil extends Student {
    
      // 属性的重写
      // 只有父类中val定义的属性可以在子类中重写
      // 父子类中不允许存在同名的var定义的属性!!!
      override val versionUID: Long = 3248203578L
    
      // 明确的使用override来定义
      override def study(): Unit = println("the pupil is studying")
    }
  8. 如果需要判断对象是否是某一个类型,那么可以使用isInstanceOf

    println(s.isInstanceOf[Pupil])
  9. 类型转换文章来源地址https://www.toymoban.com/news/detail-850148.html

    val p = s.asInstanceOf[Pupil]

到了这里,关于Scala详解(3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 大数据技术——使用IDEA开发Scala程序

    一、使用IDEA开发WordCount程序... 3 二、实验目的... 3 三、实验要求... 3 四、实验环境... 3 五、实验步骤... 3 4.1.1启动IDEA并创建一个新项目WordCount 3 4.1.2为WordCount项目添加Scala框架支持... 7 4.1.3数据准备... 8 4.1.4设置项目目录... 9 4.1.5新建Scala代码文件... 10 4.1.6配置pom.xml文件... 12

    2024年02月09日
    浏览(27)
  • 大数据Spark SparkSession的3种创建方式 Scala语言实现

    SparkSession是Apache Spark 2.0版本引入的一个编程接口,用于与Spark进行交互。它是Spark应用程序的入口点,提供了一种方便的方式来创建DataFrame、DataSet和SQLContext等数据结构,并且可以配置各种Spark应用程序的选项。SparkSession还管理了Spark应用程序的运行环境,包括Spark集群的连接,

    2023年04月20日
    浏览(25)
  • Spark大数据分析与实战笔记(第一章 Scala语言基础-3)

    对于每一门编程语言来说,数组(Array)都是重要的数据结构之一,主要用来存储数据类型相同的元素。Scala中的数组分为定长数组和变长数组,定义定长数组,需要使用new,而定义变长数组时,则需要导包 import scala.collection.mutable.ArrayBuffer 。 数组(Array)主要用来存储

    2024年02月10日
    浏览(39)
  • Spark大数据分析与实战笔记(第一章 Scala语言基础-2)

    Spark是专为大规模数据处理而设计的快速通用的计算引擎,它是由Scala语言开发实现的,关于大数据技术,本身就是计算数据,而Scala既有面向对象组织项目工程的能力,又具备计算数据的功能,同时Spark和Scala的紧密集成,本书将采用Scala语言开发Spark程序,所以学好Scala将有助

    2024年02月11日
    浏览(40)
  • Spark大数据分析与实战笔记(第一章 Scala语言基础-1)

    Spark是专为大规模数据处理而设计的快速通用的计算引擎,它是由Scala语言开发实现的,关于大数据技术,本身就是计算数据,而Scala既有面向对象组织项目工程的能力,又具备计算数据的功能,同时Spark和Scala的紧密集成,本书将采用Scala语言开发Spark程序,所以学好Scala将有助

    2024年02月11日
    浏览(40)
  • 你知道Scala编程语言吗?Scala基础教程【建议收藏】

    作者:i阿极 作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!👍👍👍 📜📜📜如果有小伙伴需要数据集和学习交流,文章下方有交流学习区!一起学习进步!💪 Scala是一种

    2023年04月08日
    浏览(68)
  • Scala语言入门以及基本语法

    scala在一种简洁的高级语言中结合了面向对象和函数式编程。Scala的静态类型有助于避免复杂应用程序中的错误,它的JVM和JavaScript运行时使您可以构建高性能系统,并轻松访问庞大的库生态系统。 几大特性 Scala运行在JVM上,因此Java和Scala实现完全无缝集成。 类型推理。 并发

    2024年02月01日
    浏览(30)
  • Scala安装步骤详解

    通过浏览器查找Scastie并进入,即可进入Scala在线运行环境。 进入Scastie界面后,在上窗格中输入“println(“hello world”)”。 单击“Run”按钮,输出信息将显示在下窗格中,如下图。 2.Scala运行环境众多,可以运行在Windows、Linux、macOS等系统上。Scala是运行在JVM上的语言,因此 必

    2024年02月07日
    浏览(25)
  • Scala详解(1)

    概述 Scala是Martin Ordersky(马丁.奥德斯科/基)于2001年开始设计的一门支持面向对象( Object-oriented )和函数式编程( Functional Programming )的多范式语言 Scala的官网:www.scala-lang.org Scala目前为止有3个大版本:Scala1.X~3.X。目前Scala1.X已经停止使用,Scala3.x兼容Scala2.x的所有特性,但是Scala3

    2024年04月15日
    浏览(22)
  • Scala详解(3)

    柯里化( Currying ) 柯里化指的是将多个参数的函数变成接收单一参数的过程 案例 柯里化本质上还是闭包!!! 传名参数 案例 案例 懒加载 在函数的返回值之前用 lazy 来修饰,这个函数就会被推迟执行,直到结果被使用的时候,函数才会执行,这个过程就称之为懒加载,或者

    2024年04月13日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包