【Scala】——面向对象

1 Scala 包

1.1 包风格

  Scala 有两种包的管理风格。

  1. 第一种 Java 的包管理风格相同,每个源文件一个包(包 名和源文件所在路径不要求必须一致),包名用“.”进行分隔以表示包的层级关系,如 com.atguigu.scala。
  2. 另一种风格,通过嵌套的风格表示层级关系,一个源文件中可以声明多个 package,子包中的类可以直接访问父包中的内容,而无需导包
package com {package scala {package chapter06 {object TestPackage {def main(args: Array[String]): Unit = {println("package test!")}}}}
}
package com {import com.scala.chapter06.other.Inner.in //父包访问子包需要导包package scala {package chapter06 {object TestPackage {val out: String = "out"def main(args: Array[String]): Unit = {println("package test!")println(in)}}package other {object Inner {val in: String = "in"def main(args: Array[String]): Unit = {println(TestPackage.out) //子包访问父包无需导包}}}}}}

1.2 包对象

  1. 在 Scala 中可以为每个包定义一个同名的包对象,定义在包对象中的成员,作为其对 应包下所有 class 和 object 的共享变量,可以被直接访问。
  2. 若使用 Java 的包管理风格,则包对象一般定义在其对应包下的 package.scala 文件中,包对象名与包名保持一致。
    在这里插入图片描述
package com.scalapackage object chapter06 {}
  1. 如采用嵌套方式管理包,则包对象可与包定义在同一文件中,但是要保证包对象 与包声明在同一作用域中。
package com {package scala {package chapter06 {object TestPackage {val out: String = "out"def main(args: Array[String]): Unit = {println("package test!")println(in)}}}}
}
package object com {val shareValue = "share"def shareMethod() = {}
}

1.3 导包

  1. 和 Java 一样,可以在顶部使用 import 导入,在这个文件中的所有类都可以使用。
  2. 局部导入:什么时候使用,什么时候导入。在其作用范围内都可以使用
  3. 通配符导入:import java.util._
  4. 给类起名:import java.util.{ArrayList=>JL}
  5. 导入相同包的多个类:import java.util.{HashSet, ArrayList}
  6. 屏蔽类:import java.util.{ArrayList =>,}
  7. 导入包的绝对路径:new root.java.util.HashMap
  8. Scala 中的三个默认导入的包
import java.lang._ 
import scala._ 
import scala.Predef._ 

1.4包访问权限

  1. Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字。
  2. private 为私有权限,只在类的内部和伴生对象中可用。
  3. protected 为受保护权限,Scala 中受保护权限比 Java 中更严格,同类、子类可以访问,同包无法访问。
  4. private[包名]增加包访问权限,包名下的其他类也可以使用
package com.scala
package chapter06class Person {private var name: String = "bobo"protected var age: Int = 18private[chapter06] var sex: String = "男"def say(): Unit = {println(name)}
}object Person {def main(args: Array[String]): Unit = {val person = new Personperson.say()println(person.name)println(person.age)}
}class Teacher extends Person {def test(): Unit = {this.agethis.sex}
}class Animal {def test: Unit = {new Person().sex}
}

2 类和对象

2.1 类

  1. 语法
[修饰符] class 类名 {类体
} 
  1. Scala 语法中,类并不声明为 public,所有这些类都具有公有可见性(即默认就是public)
  2. 一个 Scala 源文件可以包含多个类

2.1 属性

  1. 语法
[修饰符] var|val 属性名称 [:类型] = 属性值
var name: String = "bobo"
  1. Bean 属性(@BeanPropetry),可以自动生成规范的 setXxx/getXxx 方法
package com.scala
package chapter06
import scala.beans.BeanProperty
class Person {//Bean 属性(@BeanProperty)@BeanProperty var sex: String = "男"
}
object Person {def main(args: Array[String]): Unit = {var person = new Person()person.setSex("女")println(person.getSex)}
}
  1. _表示给属性一个默认值
package com.scala
package chapter06
import scala.beans.BeanProperty
class Person {var age: Int = _ // _表示给属性一个默认值
}object Person {def main(args: Array[String]): Unit = {var person = new Person()println(person.age)}
}
  1. val 修饰的属性不能赋默认值,必须显示指定
//val school: Int = _ // _表示给属性一个默认值

2.3 方法

def 方法名(参数列表) [:返回值类型] = {方法体
}

2.4 创建对象

  1. 语法
val | var 对象名 [:类型] = new 类型()
  1. val 修饰对象,不能改变对象的引用(即:内存地址),可以改变对象属性的值。
  2. var 修饰对象,可以修改对象的引用和修改对象的属性值
  3. 自动推导变量类型不能多态,所以多态需要显示声明
  4. 案例
class Person {var name: String = "canglaoshi"
}
object Person {def main(args: Array[String]): Unit = {//val 修饰对象,不能改变对象的引用(即:内存地址),可以改变对象属 性的值。val person = new Person()person.name = "bobo"// person = new Person()// 错误的println(person.name)}
}

2.5 构造器

  1. Scala 类的构造器包括:主构造器和辅助构造器
  2. 语法
class 类名(形参列表) { // 主构造器// 类体def this(形参列表) { // 辅助构造器}def this(形参列表) { //辅助构造器可以有多个...}
}
  1. 辅助构造器,函数的名称 this,可以有多个,编译器通过参数的个数及类型来区分。
  2. 辅助构造方法不能直接构建对象,必须直接或者间接调用主构造方法。
  3. 构造器调用其他另外的构造器,要求被调用构造器必须提前声明。
  4. 如果主构造器无参数,小括号可省略,构建对象时调用的构造方法的小括号也可 以省略。
  5. 案例
class Person {var name: String = _var age: Int = _def this(age: Int) {this()this.age = ageprintln("辅助构造器")}def this(age: Int, name: String) {this(age)this.name = name}println("主构造器")
}object Person {def main(args: Array[String]): Unit = {val person2 = new Person(18)}
}

2.6 构造器参数

  Scala 类的主构造器函数的形参包括三种类型:未用任何修饰、var 修饰、val 修饰

  1. 未用任何修饰符修饰,这个参数就是一个局部变量
  2. var 修饰参数,作为类的成员属性使用,可以修改
  3. val 修饰参数,作为类只读属性使用,不能修改
class Person(name: String, var age: Int, val sex: String) {
}
object Test {def main(args: Array[String]): Unit = {var person = new Person("bobo", 18, "男")// (1)未用任何修饰符修饰,这个参数就是一个局部变量//printf(person.name)// (2)var 修饰参数,作为类的成员属性使用,可以修改person.age = 19println(person.age)// (3)val 修饰参数,作为类的只读属性使用,不能修改// person.sex = "女"println(person.sex)}
}

3 封装

  封装就是把抽象出的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它 部分只有通过被授权的操作(成员方法),才能对数据进行操作。
  Scala 中的 public 属性,底层实际为 private,并通过 get 方法(obj.field())和 set 方法 (obj.field_=(value))对其进行操作。所以 Scala 并不推荐将属性设为 private,再为其设置 public 的 get 和 set 方法的做法。但由于很多 Java 框架都利用反射调用 getXXX 和 setXXX 方 法,有时候为了和这些框架兼容,也会为 Scala 的属性设置 getXXX 和 setXXX 方法(通过 @BeanProperty 注解实现)。

4 继承&多态

  1. 语法
class 子类名 extends 父类名 { 类体 }
  1. 子类继承父类的属性和方法
  2. scala 是单继承
  3. 继承的调用顺序:父类构造器->子类构造器
class Person(nameParam: String) {var name = nameParamvar age: Int = _def this(nameParam: String, ageParam: Int) {this(nameParam)this.age = ageParamprintln("父类辅助构造器")}println("父类主构造器")
}class Emp(nameParam: String, ageParam: Int) extendsPerson(nameParam, ageParam) {var empNo: Int = _def this(nameParam: String, ageParam: Int, empNoParam: Int) {this(nameParam, ageParam)this.empNo = empNoParamprintln("子类的辅助构造器")}println("子类主构造器")
}object Person{def main(args: Array[String]): Unit = {new Emp("z3", 11, 1001)}
}

在这里插入图片描述
5. 动态绑定:Scala 中属性和方法都是动态绑定,而 Java 中只有方法为动态绑定。

class Person {val name: String = "person"def hello(): Unit = {println("hello person")}
}
class Teacher extends Person {override val name: String = "teacher"override def hello(): Unit = {println("hello teacher")}
}
object Test {def main(args: Array[String]): Unit = {val teacher: Teacher = new Teacher()println(teacher.name)teacher.hello()println("----------------------------------------")val teacher1:Person = new Teacherprintln(teacher1.name)teacher1.hello()}
}

在这里插入图片描述

5 抽象类

5.1 语法

  1. 定义抽象类
abstract class Person{} //通过 abstract 关键字标记抽象类
  1. 定义抽象属性
val|var name:String //一个属性没有初始化,就是抽象属性
  1. 定义抽象方法
def hello():String //只声明而没有实现的方法,就是抽象方法
abstract class Person {val name: Stringdef hello(): Unit
}
class Teacher extends Person {val name: String = "teacher"def hello(): Unit = {println("hello teacher")}
}

5.2 继承&重写

  1. 如果父类为抽象类,那么子类需要将抽象的属性和方法实现,否则子类也需声明为抽象类
  2. 重写非抽象方法需要用 override 修饰,重写抽象方法则可以不加 override。
  3. 子类中调用父类的方法使用 super 关键字
  4. 子类对抽象属性进行实现,父类抽象属性可以用 var 修饰;子类对非抽象属性重写,父类非抽象属性只支持 val 类型,而不支持 var。因为 var 修饰的为可变变量,子类继承之后就可以直接使用,没有必要重写

5.3 匿名子类

  和 Java 一样,可以通过包含带有定义或重写的代码块的方式创建一个匿名的子类。

abstract class Person {val name: Stringdef hello(): Unit
}
object Test {def main(args: Array[String]): Unit = {val person = new Person {override val name: String = "teacher"override def hello(): Unit = println("hello teacher")}}
}

6 单例对象(伴生对象)

6.1 概述

  Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概 念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象 来模拟类对象,该对象为单例对象。若单例对象名与类名一致,则称该单例对象这个类的伴生对象,这个类的所有“静态”内容都可以放置在它的伴生对象中声明

6.2 语法

object Person{ val country:String="China" }
  1. 单例对象采用 object 关键字声明
  2. 单例对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致。
  3. 单例对象中的属性和方法都可以通过伴生对象名(类名)直接调用访问。
//(1)伴生对象采用 object 关键字声明
object Person {var country: String = "China"
}
//(2)伴生对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致。
class Person {var name: String = "bobo"
}
object Test {def main(args: Array[String]): Unit = {//(3)伴生对象中的属性和方法都可以通过伴生对象名(类名)直接调用访 问。println(Person.country)}
}

6.3 apply 方法

  1. 通过伴生对象的 apply 方法,实现不使用 new 方法创建对象。
  2. 如果想让主构造器变成私有的,可以在()之前加上 private。
  3. apply 方法可以重载。
  4. Scala 中 obj(arg)的语句实际是在调用该对象的 apply 方法,即 obj.apply(arg)。用以统一面向对象编程和函数式编程的风格。
  5. 当使用 new 关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构建对象时,调用的其实时伴生对象的 apply 方法
object Test {def main(args: Array[String]): Unit = {//(1)通过伴生对象的 apply 方法,实现不使用 new 关键字创建对象。val p1 = Person()println("p1.name=" + p1.name)val p2 = Person("bobo")println("p2.name=" + p2.name)}
}
//(2)如果想让主构造器变成私有的,可以在()之前加上 private
class Person private(cName: String) {var name: String = cName
}
object Person {def apply(): Person = {println("apply 空参被调用")new Person("xx")}def apply(name: String): Person = {println("apply 有参被调用")new Person(name)}
}

7 特质

7.1 概述

   Scala 语言中,采用特质 trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字 trait 声明。
  Scala 中的 trait 中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可以混入(mixin)多个特质。这种感觉类似于 Java 中的抽象类。
  Scala 引入 trait 特征,第一可以替代 Java 的接口,第二个也是对单继承机制的一种补充。

7.2 语法&说明

  1. 声明
trait 特质名 { trait 主体 
} 
trait PersonTrait {// 声明属性var name:String = _// 声明方法def eat():Unit={}// 抽象属性var age:Int// 抽象方法def say():Unit
}
  1. 一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素, 所以在使用时,也采用了 extends 关键字,如果有多个特质或存在父类,那么需要采用 with 关键字连接。
  2. 类和特质的关系:使用继承的关系。
  3. 当一个类去继承特质时,第一个连接词是 extends,后面是 with。
  4. 如果一个类在同时继承特质和父类时,应当把父类写在 extends 后。
没有父类:class 类名 extends 特质 1 with 特质 2 with 特质 3 …
有父类:class 类名 extends 父类 with 特质 1 with 特质 2 with 特质 3
  1. 特质可以同时拥有抽象方法和具体方法
  2. 一个类可以混入(mixin)多个特质
  3. 所有的 Java 接口都可以当做 Scala 特质使用
  4. 动态混入:可灵活的扩展类的功能
    动态混入:创建对象时混入 trait,而无需使类混入该 trait
    如果混入的 trait 中有未实现的方法,则需要实现
package com.scala
package chapter07trait PersonTrait {//(1)特质可以同时拥有抽象方法和具体方法// 声明属性var name: String = _// 抽象属性var age: Int// 声明方法def eat(): Unit = {println("eat")}// 抽象方法def say(): Unit
}
trait SexTrait {var sex: String
}//(2)一个类可以实现/继承多个特质
//(3)所有的 Java 接口都可以当做 Scala 特质使用
class Teacher extends PersonTrait with java.io.Serializable {override def say(): Unit = {println("say")}override var age: Int = _
}
object TestTrait {def main(args: Array[String]): Unit = {val teacher = new Teacherteacher.say()teacher.eat()//(4)动态混入:可灵活的扩展类的功能val t2 = new Teacher with SexTrait {override var sex: String = "男"}//调用混入 trait 的属性println(t2.sex)}
}

7.3 特质叠加

  由于一个类可以混入(mixin)多个 trait,且 trait 中可以有具体的属性和方法,若混入的特质中具有相同的方法(方法名,参数列表,返回值均相同),必然会出现继承冲突问题。冲突分为以下两种

  1. 一个类(Sub)混入的两个 trait(TraitA,TraitB)中具有相同的具体方法,且两个 trait 之间没有任何关系,解决这类冲突问题,直接在类(Sub)中重写冲突方法。
    在这里插入图片描述

  2. 一个类(Sub)混入的两个 trait(TraitA,TraitB)中具有相同的具体方法,且两个 trait 继承自相同的 trait(TraitC),及所谓的“钻石问题”,解决这类冲突问题,Scala采用了特质叠加的策略。
    在这里插入图片描述
    所谓的特质叠加,就是将混入的多个 trait 中的冲突方法叠加起来

7.4 特质叠加执行顺序

package com.scala
package chapter07trait Ball {def describe(): String = {"ball"}
}trait Color extends Ball {override def describe(): String = {"blue-" + super.describe()}
}trait Category extends Ball {override def describe(): String = {"foot-" + super.describe()}
}class MyBall extends Category with Color {override def describe(): String = {"my ball is a " + super.describe()}
}object TestTrait1 {def main(args: Array[String]): Unit = {println(new MyBall().describe())}
}
  1. 当一个类混入多个特质的时候,scala 会对所有的特质及其父特质按照一定的顺序进行 排序,而此案例中的 super.describe()调用的实际上是排好序后的下一个特质中的 describe() 方法。
  2. 叠加规则:
    在这里插入图片描述
  3. 案例中的 super,不是表示其父特质对象,而是表示上述叠加顺序中的下一个特质, 即,MyClass 中的 super 指代 Color,Color 中的 super 指代 Category,Category 中的 super 指代 Ball。
  4. )如果想要调用某个指定的混入特质中的方法,可以增加约束:super[],例如super[Category].describe()。

7.5 特质喝抽象类的区别

  1. 优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
  2. 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数, 而特质不行(有无参构造)。

8 扩展

8.1 类型检查和转换

  1. obj.isInstanceOf[T]:判断 obj 是不是 T 类型。
  2. obj.asInstanceOf[T]:将 obj 强转成 T 类型。
  3. classOf 获取对象的类名。
package com.scala
package chapter07class Person {
}object Person {def main(args: Array[String]): Unit = {val person = new Person//(1)判断对象是否为某个类型的实例val bool: Boolean = person.isInstanceOf[Person]if (bool) {//(2)将对象转换为某个类型的实例val p1: Person = person.asInstanceOf[Person]println(p1)}//(3)获取类的信息val pClass: Class[Person] = classOf[Person]println(pClass)}
}

8.2 枚举类和应用类

  1. 枚举类:需要继承 Enumeration
  2. 应用类:需要继承 App
package com.scala
package chapter07object Test {def main(args: Array[String]): Unit = {println(Color1.YELLOW)}
}// 枚举类
object Color1 extends Enumeration {val RED = Value(1, "red")val YELLOW = Value(2, "yellow")val BLUE = Value(3, "blue")
}
// 应用类
object Test20 extends App {println("xxxxxxxxxxx");
}

8.3 Type 定义新类型

  使用 type 关键字可以定义新的数据数据类型名称,本质上就是类型的一个别名

object Test {def main(args: Array[String]): Unit = {type S=Stringvar v:S="abc"def test():S="xyz"}
}

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

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

相关文章

遥感单通道图像保存为彩色图像

系列文章目录 第一章PIL单通道图像处理 文章目录 系列文章目录前言一、代码实现二、问题记录在这里插入图片描述 总结 前言 将单通道图像以彩色图像的形式进行保存主要使用了PIL库 一、代码实现 palette_data [***]:可以进行自定义设置 代码如下: fr…

UVa12304 2D Geometry 110 in 1!

题目链接 UVa12304 2D Geometry 110 in 1! 题意 这是一个拥有6(二进制是110)个子问题的2D几何问题集。 1 CircumscribedCircle x1 y1 x2 y2 x3 y3:求三角形(x1,y1)-(x2,y2)-(x3,y3)的外接圆。这3点保证不共线。答案应格式化成(x,y,r…

服务器 配置git

参考了下面这篇文章,不对的地方做了改正 在服务器上git clone github项目的过程-CSDN博客 1. 下载解压 wget https://www.kernel.org/pub/software/scm/git/git-2.34.1.tar.gz tar -zxvf git-2.34.1.tar.gz 2. 安装 cd git-2.34.1/ ./configure make confi…

Geotools-PG空间库(Crud,属性查询,空间查询)

建立连接 经过测试,这套连接逻辑除了支持纯PG以外,也支持人大金仓,凡是套壳PG的都可以尝试一下。我这里的测试环境是Geosence创建的pg SDE,数据库选用的是人大金仓。 /*** 获取数据库连接资源** param connectConfig* return* {…

springboot私人健身与教练预约管理系统源码和论文

随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&#xf…

【rk3568】01-环境搭建

文章目录 1.开发板介绍1.1相关资源:1.2接口布局1.3屏幕1.4核心板引脚可复用资源 2.环境搭建2.1安装依赖包2.2git配置2.3安装sdk2.4sdk介绍2.5sdk编译 3.镜像介绍 1.开发板介绍 开发板:atk-rk3568开发板 eMMC:64G LPDDR4:4G 显示屏…

螺旋数字矩阵 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法: 给出数字个数n和行数m (0 < n <= 999,0 < m <= 999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出2,3……

创建ROS模型与小机器人地图规划

1、打开自己的VM系统 2、安装小机器人的安装包&#xff0c;输入如下命令&#xff0c;回车输入密码(自己设的)&#xff1a; sudo apt install ros-noetic-turtlebot3-simulations ros-noetic-turtlebot3-slam ros-noetic-turtlebot3-navigation 提示我之前安装过了 3、用rosla…

Java 常见缓存详解以及解决方案

一. 演示Mybatis 一级缓存 首先我们准备一个接口 两个实现的方法&#xff0c; 当我们调用这个queryAll&#xff08;&#xff09;方法时我们需要调用selectAll&#xff08;&#xff09;方法来查询数据 调用此接口实现效果 这个时候我们就可以发现了问题&#xff0c;我们调用方法…

18张AI电脑动漫超清壁纸免费分享

18张AI电脑动漫壁纸&#xff0c;紫色系和暗黑系&#xff0c;都很不错&#xff0c;喜欢的朋友可以拿去 CSDN免积分下载

【LV12 DAY12-13 GPIO C 语言与寄存器封装】

GPIO 通用型输入输出&#xff0c;GPIO可以控制连接在其引脚实现信号的输入和输出 芯片的引脚和外部设备相连从而实现与外部硬件的通讯&#xff0c;控制&#xff0c;信号采集的功能。 控制CHG_COK引脚输出为高电平&#xff0c;LED亮&#xff0c;输出为低电平&#xff0c;LED熄灭…

Android 10.0 TvSettings系统设置wifi连接密码框点击Enter键失去焦点

1.前言 在10.0的box产品开发中,在TvSettings中,在wifi连接的时候,在用遥控器输入wifi密码框的时候,会发现在按遥控器Enter键的时候, 发现EditText焦点失去了,导致输入法消失了,为了解决这个问题就需要拦截Enter键保证正常输入wifi密码,接下来就来实现这个功能 如图: 2.…

CSS 弹幕按钮动画

<template><view class="content"><button class="btn-23"><text class="text">弹幕按钮</text><text class="marquee">弹幕按钮</text></button></view></template><…

win7添加access的odbc数据源

从控制面板打开odbc数据源&#xff1b;如果像下面没有access的驱动程序&#xff0c; 根据资料&#xff0c;打开C盘-Windows-SysWow64-odbcad32.exe&#xff0c;看一下就有了&#xff1b; 然后添加用户DSN&#xff0c;选中access的驱动程序&#xff0c; 自己输入一个数据源名&am…

【浅尝C++】引用

&#x1f388;归属专栏&#xff1a;浅尝C &#x1f697;个人主页&#xff1a;Jammingpro &#x1f41f;记录一句&#xff1a;大半夜写博客的感觉就是不一样&#xff01;&#xff01; 文章前言&#xff1a;本篇文章简要介绍C中的引用&#xff0c;每个介绍的技术点&#xff0c;在…

Gitlab-ci:从零开始的前端自动化部署

一.概念介绍 1.1 gitlab-ci && 自动化部署工具的运行机制 以gitlab-ci为例&#xff1a; (1) 通过在项目根目录下配置.gitlab-ci.yml文件&#xff0c;可以控制ci流程的不同阶段&#xff0c;例如install/检查/编译/部署服务器。gitlab平台会扫描.gitlab-ci.yml文件&…

QML实现的图片浏览器

很久之前实现了一个QWidget版本的图片浏览器:基于Qt5的图片浏览器QHImageViewer 今天用QML也实现一个,功能差不多: ●悬浮工具栏 ●支持图片缩放、旋转、还原、旋转、拖动。 ●拖动图片时,释放鼠标图片会惯性滑动。 ●支持左右翻页查看文件夹中的图片。 ●支持保存图片至本…

【ONE·MySQL || 常见的基本函数】

总言 主要内容&#xff1a;介绍了MySQL中常用的基本函数。一些聚合函数、时间日期函数、字符串函数、数字函数等。       文章目录 总言1、聚合函数1.1、汇总1.2、COUNT()函数1.2.1、基本说明1.2.2、使用演示 1.3、SUM( )函数1.3.1、基本说明1.3.2、使用演示 1.4、AVG( )函…

java基础之Java8新特性-Optional

目录 1.简介 2.Optional类常用方法 3.示例代码 4.示例代码仓库地址 1.简介 Java 8引入了一个重要的新特性&#xff0c;即Optional类。Optional类是为了解决空指针异常而设计的。 在Java中&#xff0c;当我们尝试访问一个空对象的属性或调用其方法时&#xff0c;很容易抛出…

【服务器数据恢复】Hyper-V虚拟化数据恢复案例

服务器数据恢复环境&#xff1a; Windows Server操作系统服务器&#xff0c;部署Hyper-V虚拟化环境&#xff0c;虚拟机的硬盘文件和配置文件存放在某品牌MD3200存储中&#xff0c;MD3200存储中有一组由4块硬盘组成的raid5阵列&#xff0c;存放虚拟机的数据文件&#xff1b;另外…