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 bprintln(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-10var i = 1while (i <= 10) {println(i)i += 1}
    ​println("=" * 50)
    ​// 会发现,对于while循环,可以拆分成两部分// 1. 条件 - 在定义while结构的时候,并不知道条件是什么,而是用户在使用的时候来传入。//    对于开发人员而言,只需要确定一件事就可以:条件的结果一定是一个Boolean型// 2. 执行逻辑 - 在定义while结构的时候,需要执行什么逻辑,开发人员不知道//def whileLoop(condition: => Boolean)(body: => Unit): Unit = {// 判断条件是否成立if (condition) {// 只要条件成立,那么就执行逻辑bodywhileLoop(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 Personp.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 Rectangler.height = 5.2println(r.height)r.width = 4.5println(r.width)println(r.area)
    ​}
    ​
    }
    ​
    class Rectangle {
    ​// 在Scala中,推荐属性使用_开头,和方法做区分private var _height: Double = _private var _width: Double = _
    ​/*def setHeight(height: Double): Unit = this._height = heightdef 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.ArrayListval 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 testobject PackageDemo {def main(args: Array[String]): Unit = {println(test.add(3, 7))println(test.id)}}package object test {val id = 5846def add(x: Int, y: Int): Int = x + y}
  4. 在Scala中,可以将这个包中所有的类共享的属性或者函数定义到包对象中

面向对象的特征

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

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

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

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

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

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

    package com.fesco.dtobject ExtendsDemo {def main(args: Array[String]): Unit = {val s: Student = new Pupils.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.dtobject ExtendsDemo {def main(args: Array[String]): Unit = {val s: Student = new Pupils.study()println(s.versionUID)}}class Student {val versionUID: Long = 54896524Ldef 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. 类型转换

    val p = s.asInstanceOf[Pupil]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/813024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WinForms零基础进阶控件教程(超实用详细版)

文章目录 树型控件TreeView常用属性常用事件添加、删除树节点通过代码添加树节点通过代码删除树节点&#xff1a;管理节点图标响应事件&#xff0c;获取选中节点 列表视图ListView常用属性常用事件添加、删除项使用ListViewItem集合编辑器添加&#xff0c;删除项&#xff1a;通…

神州数码2024春招Java笔试(原题)

一、单选题&#xff08;35题&#xff0c;每题2分&#xff09; 1、(2分)【单选题】以下用于修改数据库字段名称的SQL语句是&#xff08;&#xff09; A.RENAME B.CHANGE C.ALTER D.MODIFY 2、(2分)【单选题】若一棵二叉树的前序遍历为a,e, b, d. c&#xff0c;后序遍历为 b, …

LED显示IC-点阵数码管显示驱动/抗干扰数码管驱动VK1650 SOP16/DIP16

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK1650 封装形式&#xff1a;SOP16/DIP16 概述 VK1650是一种带键盘扫描电路接口的 LED 驱动控制专用芯片&#xff0c;内部集成有数据锁存器、LED 驱动、键盘扫描等电路。SEG脚接LED阳极&#xff0c;GRID脚接LED阴极&…

WebGL 2.0相较于1.0有什么不同?

作者&#xff1a;STANCH 1.概述 WebGL 1.0自推出以来&#xff0c;已成为广泛支持的Web标准&#xff0c;既能跨平台&#xff0c;还免版税。它通过插件为Web浏览器带来高质量的3D图形&#xff0c;这是迄今为止市场上使用最广泛的Web图形&#xff0c;并得到Apple&#xff0c;Goog…

ControllerAdvice用法

ControllerAdvice用法 ControllerAdvice是一个组件注解&#xff0c;它允许你在一个地方处理整个应用程序控制器的异常、绑定数据和预处理请求。这意味着你不需要在每个控制器中重复相同的异常处理代码&#xff0c;从而使得代码更加简洁、易于管理。 主要特性 全局异常处理&a…

【vue】v-model.lazy等(非实时渲染)

v-model&#xff1a;实时渲染v-model.lazy&#xff1a;失去焦点/按回车后&#xff0c;才渲染v-model.number&#xff1a;值转换为数字v-model.trim&#xff1a;去除首尾空格 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

MDK平台 - Code, RO-data , RW-data, ZI-data详解

文章目录 1 . 前言2 . Code, RO-data , RW-data, ZI-data解析3 . RAM上电复位4 . 细节扩展5 . 总结 【全文大纲】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 1 . 前言 MDK编译后&#xff0c;会列出Code, RO-data , RW-data, ZI-data&#xff0c;以下解析…

股票价格预测 | Python使用LSTM预测股票价格

文章目录 效果一览文章概述代码设计效果一览 文章概述 Python使用LSTM预测股票价格 代码设计 import pandas as pd import matplotlib.pyplot as plt import numpy as np import tensorflowfrom numpy import

我可以信任XEX吗?

在数字货币领域&#xff0c;安全一直是我们最为关注的话题之一。作为一个积极参与加密货币交易的投资者&#xff0c;我深知选择一个安全可靠的交易所至关重要。在众多交易所中&#xff0c;我发现XEX是最安全的交易所之一。 每当我想要进行加密货币交易时&#xff0c;第一件事就…

git合并冲突

git合并冲突 问题描述 Auto-merging mes5server/mes5j.json Auto-merging mes5server/mes5j.json CONFLICT (content): Merge conflict in mes5server/mes5j.json Automatic merge failed; fix conflicts and then commit the result.原因 要合并的两个分支改动了同一份文件…

深入理解MySQL中的log_bin_trust_function_creators系统变量

在MySQL数据库管理中&#xff0c;尤其是在涉及到数据复制与恢复的情境下&#xff0c;二进制日志&#xff08;Binary Log&#xff09;扮演着至关重要的角色。它忠实记录了对数据库内容进行修改的SQL语句&#xff0c;为数据同步、故障恢复等任务提供了关键信息。然而&#xff0c;…

K8S资源管理之LimitRange

资源配置范围管理&#xff1a;LimitRange 在默认情况下&#xff0c;Kubernetes不会对Pod加CPU和内存的限制&#xff0c;这意味着Kubernetes系统中的任何Pod都可以使用其节点的所有可用的CPU和内存。 如果一个机器的Pod特别多&#xff0c;我们又不愿意为每个Pod都配置上…

2024年蓝牙耳机哪个品牌最好?五大热门机型PK,新手必看!

​随着生活节奏的加快&#xff0c;蓝牙耳机已经成为了我们日常生活中不可或缺的伙伴。它不仅让我们的听音乐、观看视频和通话变得更加便捷&#xff0c;还带来了无线的自由体验。面对市场上众多的选择&#xff0c;我为你精挑细选了几款表现优异的蓝牙耳机&#xff0c;希望能帮助…

mybiats-puls-插入测试以及雪花算法

一&#xff0c;测试 /* * 插入测试 * */ Test public void test01() {User user new User();/** 自动帮我们生成id* */user.setName("kuku");user.setAge(3);user.setEmail("2983394967qq.com");final int insert mapper.insert(user);System.out.print…

Redis从入门到精通(十六)多级缓存(一)Caffeine、JVM进程缓存

文章目录 第6章 多级缓存6.1 什么是多级缓存&#xff1f;6.2 搭建测试项目6.2.1 项目介绍6.2.2 新增商品表6.2.3 编写商品相关代码6.2.4 启动服务并测试6.2.5 导入商品查询页面&#xff0c;配置反向代理 6.3 JVM进程缓存6.3.1 Caffeine6.3.2 实现JVM进程缓存6.3.2.1 需求分析6.…

基于springboot仿雀语的文档管理系统

项目介绍 本项目借鉴了雀语的一些UI设计&#xff0c;实现了文档在线管理的功能&#xff0c;知识库可以对不同分类的文档建立不同的库&#xff0c;知识库里面左边可以维护菜单菜单目录&#xff0c;右边实现在线预览。该项目可以防止用户下载和复制文档&#xff0c;只支持在线预…

TSINGSEE青犀AI智能分析网关V4吸烟/抽烟检测算法介绍及应用

抽烟检测AI算法是一种基于计算机视觉和深度学习技术的先进工具&#xff0c;旨在准确识别并监测个体是否抽烟。该算法通过训练大量图像数据&#xff0c;使模型能够识别出抽烟行为的关键特征&#xff0c;如烟雾、手部动作和口部形态等。 在原理上&#xff0c;抽烟检测AI算法主要…

Dockerfile中 CMD和ENTRYPOINT的区别

在 Dockerfile 中&#xff0c;CMD 和 ENTRYPOINT 都用于指定容器启动时要执行的命令。它们之间的主要区别是&#xff1a; - CMD 用于定义容器启动时要执行的命令和参数&#xff0c;它设置的值可以被 Dockerfile 中的后续指令覆盖&#xff0c;包括在运行容器时传递的参数。如果…

Angular 13新特性概览与升级指南

Angular 13是Angular框架的最新版本&#xff0c;它引入了一些新的特性和改进。下面是Angular 13的一些新特性概览和升级指南&#xff1a; Ivy Renderer改进&#xff1a;Angular 13进一步改进了Ivy渲染器&#xff0c;提供更好的性能和更小的包大小。这意味着你可以在应用程序中获…

如何测试PostgreSQL数据库的性能

在这篇博客里&#xff0c;我将展示如何测量 PostgreSQL 数据库服务器的性能&#xff0c;并指导你如何运行一个基准测试。 基准测试旨在评估和比较不同配置、拓扑结构、系统和组件的性能。为此&#xff0c;我将使用 pgbench 工具。 你可能会问&#xff0c;为什么要使用一个单独…