Scala第六章节

news2024/11/25 6:31:31

Scala第六章节

scala总目录

章节目标

  1. 掌握类和对象的定义
  2. 掌握访问修饰符和构造器的用法
  3. 掌握main方法的实现形式
  4. 掌握伴生对象的使用
  5. 掌握定义工具类的案例

1. 类和对象

Scala是一种函数式的面向对象语言, 它也是支持面向对象编程思想的,也有类和对象的概念。我们依然可以基于Scala语言来开发面向对象的应用程序。

1.1 相关概念

什么是面向对象?

面向对象是一种编程思想, 它是基于面向过程的, 强调的是以对象为基础完成各种操作.

面向对象的三大思想特点是什么?

1. 更符合人们的思考习惯.
2. 把复杂的事情简单化.
3. 把程序员从执行者变成指挥者.

面试题: 什么是面向对象? 思路: 概述, 特点, 举例, 总结.

什么是类?

类是属性和行为的集合, 是一个抽象的概念, 看不见, 也摸不着.
  • 属性(也叫成员变量): 名词, 用来描述事物的外在特征的.

  • 行为(也叫成员方法): 动词, 表示事物能够做什么.

  • 例如: 学生有姓名和年龄(这些是属性), 学生要学习, 要吃饭(这些是行为).

什么是对象?

对象是类的具体体现, 实现. 

面向对象的三大特征是什么?

封装, 继承, 多态.
1.2 创建类和对象

Scala中创建类和对象可以通过class和new关键字来实现. 用class来创建类, 用new来创建对象.

1.2.1 示例

创建一个Person类,并创建它的对象, 然后将对象打印到控制台上.

1.2.2 步骤
  1. 创建一个scala项目,并创建一个object类

    注意: object修饰的类是单例对象, 这点先了解即可, 稍后会详细解释.

  2. 在object类中添加main方法.

  3. 创建Person类, 并在main方法中创建Person类的对象, 然后输出结果.

1.2.3 实现
  • 在IDEA中创建项目,并创建一个object类(main方法必须放在Object中)

    • 第一步: 创建Scala项目
      在这里插入图片描述
      在这里插入图片描述

      在这里插入图片描述

    • 第二步: 创建object类.
      在这里插入图片描述
      在这里插入图片描述

  • 在object类中添加main方法, 并按照需求完成指定代码.

//案例: 测试如何在Scala程序中创建类和对象.
object ClassDemo01 {

  //1. 创建Person类
  class Person {}

  //2. 定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 创建Person类型的对象.
    val p = new Person()
    //4. 将对象打印到控制台上
    println(p)
  }
}

1.3 简写方式

用法

  • 如果类是空的,没有任何成员,可以省略{}
  • 如果构造器的参数为空,可以省略()

示例

使用简写方式重新创建Person类和对象, 并打印对象.

参考代码

//案例: 通过简写方式在Scala中创建类和对象
object ClassDemo02 {

  //1. 创建Person类
  class Person 

  //2. 定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 创建Person类型的对象.
    val p = new Person
    //4. 将对象打印到控制台上
    println(p)
  }
}

2. 定义和访问成员变量

一个类会有自己的属性,例如:人类,就有自己的姓名和年龄。我们接下来学习如何在类中定义和访问成员变量。

2.1 用法
  • 在类中使用var/val来定义成员变量
  • 对象可以通过对象名.的方式来访问成员变量
2.2 示例

需求

  1. 定义一个Person类,包含一个姓名和年龄字段
  2. 创建一个名为"张三"、年龄为23岁的对象
  3. 打印对象的名字和年龄

步骤

  1. 创建一个object类,添加main方法
  2. 创建Person类,添加姓名字段和年龄字段,并对字段进行初始化,让scala自动进行类型推断
  3. 在main方法中创建Person类对象,设置成员变量为"张三"、23
  4. 打印对象的名字和年龄

参考代码

//案例: 定义和访问成员变量.
object ClassDemo03 {

  //1. 创建Person类
  class Person {
    //2. 定义成员变量
    //val name:String = ""
    //通过类型推断来实现
    //var修饰的变量, 值是可以修改的.  val修饰的变量, 值不能修改.
    var name = ""   //姓名
    var age = 0     //年龄
  }

  //定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 创建Person类型的对象.
    val p = new Person
    //4. 给成员变量赋值
    p.name = "张三"
    p.age = 23
    //5. 打印成员变量值到控制台上
    println(p.name, p.age)
  }
}

3. 使用下划线初始化成员变量

scala中有一个更简洁的初始化成员变量的方式,可以让代码看起来更加简洁, 更优雅.

3.1 用法
  • 在定义var类型的成员变量时,可以使用_来初始化成员变量
    • String => null
    • Int => 0
    • Boolean => false
    • Double => 0.0
  • val类型的成员变量,必须要自己手动初始化
3.2 示例

需求

  1. 定义一个Person类,包含一个姓名和年龄字段
  2. 创建一个名为"张三"、年龄为23岁的对象
  3. 打印对象的名字和年龄

步骤

  1. 创建一个object类,添加main方法
  2. 创建Person类,添加姓名字段和年龄字段,指定数据类型,使用下划线初始化
  3. 在main方法中创建Person类对象,设置成员变量为"张三"、23
  4. 打印对象的名字和年龄

参考代码

//案例: 使用下划线来初始化成员变量值.
//注意: 该方式只针对于var类型的变量有效. 如果是val类型的变量, 需要手动赋值.
object ClassDemo04 {

  //1. 创建Person类
  class Person {
    //2. 定义成员变量
    var name:String = _   //姓名
    var age:Int = _       //年龄
    //val age:Int = _     //这样写会报错, 因为"下划线赋值"的方式只针对于var修饰的变量有效.
  }

  //定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 创建Person类型的对象.
    val p = new Person
    //4. 给成员变量赋值
    p.name = "张三"
    p.age = 23
    //5. 打印成员变量值到控制台上
    println(p.name, p.age)
  }
}

4. 定义和访问成员方法

类可以有自己的行为,scala中也可以通过定义成员方法来定义类的行为。

4.1 格式

在scala的类中,也是使用def来定义成员方法的.

def 方法名(参数1:数据类型, 参数2:数据类型): [return type] = {
    //方法体
}

注意: 返回值的类型可以不写, 由Scala自动进行类型推断.

4.2 示例

需求

  1. 创建一个Customer类
    在这里插入图片描述

  2. 创建一个该类的对象,并调用printHello方法

步骤

  1. 创建一个object类,添加main方法
  2. 创建Customer类,添加成员变量、成员方法
  3. 在main方法中创建Customer类对象,设置成员变量值(张三、男)
  4. 调用成员方法

参考代码

//案例: 定义和访问成员方法
object ClassDemo05 {

  //1. 创建Customer类
  class Customer {
    //2. 定义成员变量
    var name:String = _   //姓名
    var sex = ""          //性别

    //3. 定义成员方法printHello
    def printHello(msg:String) = {
      println(msg)
    }
  }

  //定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //4. 创建Customer类型的对象.
    val c = new Customer
    //5. 给成员变量赋值
    c.name = "张三"
    c.sex = "男"
    //6. 打印成员变量值到控制台上
    println(c.name, c.sex)
    //7. 调用成员方法
    printHello("你好!")
  }
}

5. 访问权限修饰符

和Java一样,scala也可以通过访问修饰符,来控制成员变量和成员方法是否可以被外界访问。

5.1 定义
  1. Java中的访问控制,同样适用于scala,可以在成员前面添加private/protected关键字来控制成员的可见性。

  2. 在scala中,没有public关键字,任何没有被标为private或protected的成员都是公共的.

    注意:
    Scala中的权限修饰符只有: private, private[this], protected, 默认这四种.

5.2 案例

需求

  • 定义一个Person类
    在这里插入图片描述

  • 在main方法中创建该类的对象,测试是否能够访问到私有成员

参考代码

//案例: 演示Scala中的访问修饰符.
/*
  注意:
    1. Scala中可以使用private/protected来修饰成员.
    2. 如果成员没有被private/protected修饰, 默认就是公共的(类似于Java中的public).
 */
object ClassDemo06 {

  //1. 创建Customer类
  class Customer {
    //2. 定义成员变量, 全部私有化
    private var name = "" //姓名
    private var age = 0 //年龄

    //3. 定义成员方法
    //获取姓名
    def getName() = name

    //设置姓名
    def setName(name: String) = this.name = name

    //获取年龄
    def getAge() = age

    //设置年龄
    def setAge(age: Int) = this.age = age

    //打招呼的方法, 该方法需要私有化.
    private def sayHello() = println("Hello, Scala!")
  }

  //定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //4. 创建Customer类型的对象.
    val c = new Customer
    //5. 给成员变量赋值
    //c.name = "张三"     //这样写会报错, 因为私有成员外界无法直接访问.
    c.setName("张三")
    c.setAge(23)
    //6. 打印成员变量值到控制台上
    println(c.getName(), c.getAge())
    //7. 尝试调用私有成员方法
    //c.sayHello()       //这样写会报错, 因为私有成员外界无法直接访问.
  }
}

6. 类的构造器

当创建对象的时候,会自动调用类的构造器。之前使用的都是默认构造器,接下来我们要学习如何自定义构造器。

6.1 分类
  • 主构造器
  • 辅助构造器
6.2 主构造器

语法

class 类名(var/val 参数名:类型 = 默认值, var/val 参数名:类型 = 默认值){
    //构造代码块
}

注意:

  • 主构造器的参数列表直接定义在类名后面,添加了val/var表示直接通过主构造器定义成员变量
  • 构造器参数列表可以指定默认值
  • 创建实例,调用构造器可以指定字段进行初始化
  • 整个class中除了字段定义和方法定义的代码都是构造代码

示例

  1. 定义一个Person类,通过主构造器参数列表定义姓名和年龄字段,并且设置它们的默认值为张三, 23
  2. 在主构造器中输出"调用主构造器"
  3. 创建"李四"对象(姓名为李四,年龄为24),打印对象的姓名和年龄
  4. 创建"空"对象,不给构造器传入任何的参数,打印对象的姓名和年龄
  5. 创建"测试"对象,不传入姓名参数,仅指定年龄为30,打印对象的姓名和年龄

参考代码

//案例: 演示Scala中的类的主构造器.
/*
  注意:
    1. Scala中主构造器的参数列表是直接写在类名后的.
    2. 主构造器的参数列表可以有默认值.
    3. 调用主构造器创建对象时, 可以指定参数赋值.
    4. 整个类中除了定义成员变量和成员方法的代码, 其他都叫: 构造代码.
 */
object ClassDemo07 {

  //1. 创建person类, 主构造器参数列表为: 姓名和年龄.
  class Person(val name: String = "张三", val age: Int = 23) { //这里应该用var修饰.
    //2. 在主构造器中输出"调用主构造器"
    println("调用主构造器!...")
  }

  //定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 创建"空"对象, 什么都不传.
    val p1 = new Person()
    println(s"p1: ${p1.name}...${p1.age}")

    //4. 创建"李四"对象, 传入姓名和年龄
    val p2 = new Person("李四", 24)
    println(s"p2: ${p2.name}...${p2.age}")

    //5. 创建测试对象, 仅传入年龄.
    val p3 = new Person(age = 30)
    println(s"p3: ${p3.name}...${p3.age}")
  }
}
6.2 辅助构造器

在scala中,除了定义主构造器外,还可以根据需要来定义辅助构造器。例如:允许通过多种方式,来创建对象,这时候就可以定义其他更多的构造器。我们把除了主构造器之外的构造器称为辅助构造器

语法

  • 定义辅助构造器与定义方法一样,也使用def关键字来定义
  • 辅助构造器的默认名字都是this, 且不能修改.
def this(参数名:类型, 参数名:类型) {
    // 第一行需要调用主构造器或者其他构造器
    // 构造器代码
}

注意: 辅助构造器的第一行代码,必须要调用主构造器或者其他辅助构造器

示例

需求

  • 定义一个Customer类,包含一个姓名和地址字段
  • 定义Customer类的主构造器(初始化姓名和地址)
  • 定义Customer类的辅助构造器,该辅助构造器接收一个数组参数,使用数组参数来初始化成员变量
  • 使用Customer类的辅助构造器来创建一个"张三"对象
    • 姓名为张三
    • 地址为北京
  • 打印对象的姓名、地址

注意:

  1. 该案例涉及到"数组"相关的知识点, 目前我们还没有学习到.
  2. Scala中的数组和Java中的数组用法基本类似, 目前能看懂即可, 后续会详细讲解.

参考代码

//案例: 演示Scala中的类的辅助构造器.
object ClassDemo08 {

  //1. 创建Customer类, 主构造器参数列表为: 姓名和地址.
  class Customer(var name: String, var address: String) { //这里应该用var修饰.
    //2. 定义一个辅助构造器, 接收一个数组参数
    def this(arr:Array[String]) {
      this(arr(0), arr(1))    //将数组的前两个元素分别传给主构造器的两个参数.
    }
  }

  //定义main函数, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 调用辅助构造器, 创建Customer对象.
    val c = new Customer(Array("张三", "北京"))
    //4. 打印结果.
    println(c.name, c.address)
  }
}

7. 单例对象

scala中是没有static关键字的,要想定义类似于Java中的static变量、static方法,就要使用到scala中的单例对象了, 也就是object.

7.1 定义单例对象

单例对象表示全局仅有一个对象, 也叫孤立对象. 定义单例对象和定义类很像,就是把class换成object.

格式

object 单例对象名{ }			//定义一个单例对象.

注意:

  1. 在object中定义的成员变量类似于Java中的静态变量, 在内存中都只有一个对象.

  2. 在单例对象中, 可以直接使用单例对象名.的形式调用成员.

示例

需求

  • 定义一个Dog单例对象,保存狗有几条腿
  • 在main方法中打印狗腿的数量

参考代码

//案例: 演示Scala中的单例对象之定义和访问成员变量.
object ClassDemo09 {

  //1. 定义单例对象Dog
  object Dog {
    //2. 定义一个变量, 用来存储狗腿子的数量
    val leg_num = 4
  }

  //定义main方法, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 打印狗腿子的数量
    println(Dog.leg_num)
  }
}
7.2 在单例对象中定义方法

在单例对象中定义的成员方法类似于Java中的静态方法.

示例

需求

  • 设计一个单例对象,定义一个能够打印分割线(15个减号)的方法
  • 在main方法调用该方法,打印分割线

参考代码

//案例: 演示Scala中的单例对象之定义和访问成员方法.
object ClassDemo10 {

  //1. 定义单例对象PrintUtil
  object PrintUtil {
    //2. 定义一个方法, 用来打印分割线
    def printSpliter() = println("-" * 15)
  }

  //定义main方法, 它是程序的主入口.
  def main(args: Array[String]): Unit = {
    //3. 调用单例对象中的成员方法
    PrintUtil.printSpliter()
  }
}

8. main方法

scala和Java一样,如果要运行一个程序,必须有一个main方法。在Java中main方法是静态的,而在scala中没有静态方法。所以在scala中,这个main方法必须放在一个单例对象中。

8.1 定义main方法

main方法

def main(args:Array[String]):Unit = {
    // 方法体
}

示例

需求

  • 创建一个单例对象,在该单例对象中打印"hello, scala"

参考代码

object Main5 {
  def main(args:Array[String]) = {
    println("hello, scala")
  }
}
8.2 继承App特质

创建一个object, 继承自App特质(Trait),然后将需要编写在main方法中的代码,写在object的构造方法体内。

object 单例对象名 extends App {
    // 方法体
}

示例

需求

  • 继承App特质,来实现一个入口。同样输出"hello, scala"

参考代码

object Main5 extends App {
  println("hello, scala")
}

9. 伴生对象

在Java中,经常会有一些类,同时有实例成员又有静态成员。例如:

public class Generals {

    private static String armsName = "青龙偃月刀";

    public void toWar() {
        //打仗
        System.out.println("武将拿着"+ armsName +", 上阵杀敌!");
    }

    public static void main(String[] args) {
        new Generals().toWar();
    }
}

在scala中,要实现类似的效果,可以使用伴生对象来实现。

9.1 定义伴生对象

一个class和object具有同样的名字。这个object称为伴生对象,这个class称为伴生类

  • 伴生对象必须要和伴生类一样的名字
  • 伴生对象和伴生类在同一个scala源文件中
  • 伴生对象和伴生类可以互相访问private属性

示例

需求

  • 编写一个Generals类,有一个toWar方法,打印

    武将拿着**武器, 上阵杀敌!		//注意: **表示武器的名字.
    
  • 编写一个Generals伴生对象,定义一个私有变量,用于保存武器名称.

  • 创建Generals对象,调用toWar方法

参考代码

//案例: 演示Scala中的伴生对象
object ClassDemo12 {

  //1. 定义一个类Generals, 作为一个伴生类.
  class Generals {    //这里写的都是非静态成员.
    //2. 定义一个toWar()方法, 输出一句话, 格式为"武将拿着**武器, 上阵杀敌!"
    def toWar() = println(s"武将拿着${Generals.armsName}武器, 上阵杀敌!")
  }

  //3. 定义一个伴生对象, 用来保存"武将的武器".
  object Generals {   //这里写的都是静态成员.
    private var armsName = "青龙偃月刀"
  }

  //定义main方法, 作为程序的主入口
  def main(args: Array[String]): Unit = {
    //4. 创建Generals类的对象.
    val g = new Generals
    //5. 调用Generals类中的toWar方法
    g.toWar()
  }
}
9.2 private[this]访问权限

如果某个成员的权限设置为private[this],表示只能在当前类中访问。伴生对象也不可以访问.

示例

示例说明

  • 定义一个Person类,包含一个name字段, 该字段用private[this]修饰
  • 定义Person类的伴生对象,定义printPerson方法
  • 测试伴生对象是否能访问private[this]权限的成员

示例代码

//案例: 测试private[this]的访问权限
object ClassDemo13 {

  //1. 定义一个Person类, 属性为: name
  class Person(private[this] var name: String)

  //2. 定义Person类的伴生对象.
  object Person {
    //3. 定义一个方法printPerson, 用来打印Person#name属性值.
    def printPerson(p:Person) = println(p.name)
  }

  //定义main函数, 它是程序的主入口
  def main(args: Array[String]) = {
    //4. 创建Person类型的对象.
    val p = new Person("张三")
    //5. 调用Person伴生对象中的printPerson方法
    Person.printPerson(p)
  }
}

注意: 上述代码,会编译报错。但移除掉[this]就可以访问了

9.3 apply方法

在Scala中, 支持创建对象的时候, 免new的动作, 这种写法非常简便,优雅。要想实现免new, 我们就要通过伴生对象的apply方法来实现。

9.3.1 格式

定义apply方法的格式

object 伴生对象名 {
	def apply(参数名:参数类型, 参数名:参数类型...) = new(...)
}

创建对象

val 对象名 = 伴生对象名(参数1, 参数2...)

例如: val p = Person(“张三”, 23)

9.3.2 示例

需求

  • 定义一个Person类,它包含两个字段:姓名和年龄
  • 在伴生对象中定义apply方法,实现创建Person对象的免new操作.
  • 在main方法中创建该类的对象,并打印姓名和年龄

参考代码

//案例: 演示Scala中的apply方法
object ClassDemo14 {

  //1. 定义Person类, 属性为姓名和年龄
  class Person(var name: String = "", var age: Int = 0)

  //2. 定义Person类的伴生对象.
  object Person {
    //3. 定义apply方法, 实现创建Person对象的时候免new.
    def apply(name:String, age:Int) = new Person(name, age)
  }

  //定义main方法, 作为程序的主入口
  def main(args: Array[String]): Unit = {
    //4. 创建Person类型的对象.
    val p = Person("张三", 23)
    //5. 打印Person对象的属性值.
    println(p.name, p.age)
  }
}

10. 案例: 定义工具类

10.1 概述

Scala中工具类的概念和Java中是一样的, 都是

1. 构造方法全部私有化, 目的是不让外界通过构造方法来创建工具类的对象.
2. 成员全部是静态化, 意味着外界可以通过"类名."的形式来访问工具类中的内容.

综上所述, 在Scala中只有object单例对象满足上述的要求.

10.2 示例

需求

  • 编写一个DateUtils工具类专门用来格式化日期时间
  • 定义一个方法,用于将日期(Date)转换为年月日字符串,例如:2030-10-05
  • 定义一个方法, 用于将年月日字符串转换为日期(Date).

步骤

  • 定义一个DateUtils单例对象
  • 在DateUtils中定义日期格式化方法(date2String)和解析字符串方法(string2Date)
  • 使用SimpleDateFormat来实现String和Date之间的相互转换

参考代码

//案例: 定义DateUtils工具类, 用于实现String和Date之间的相互转换.
object ClassDemo15 {

  //1. 定义DateUtils工具类.    //也就是Scala中的单例对象.
  object DateUtils {
    //2. 创建SimpleDateFormat类型的对象, 用来进行转换操作.
    var sdf: SimpleDateFormat = null

    //3. 定义方法date2String, 用来将Date日期对象转换成String类型的日期.
    //参数1: 日期对象,   参数2: 模板
    def date2String(date: Date, template: String):String  = {
      sdf = new SimpleDateFormat(template)
      sdf.format(date)
    }

    //4. 定义方法string2Date, 用于将String类型的日期转换成Date日期对象.
    def string2Date(dateString: String, template: String) = {
      sdf = new SimpleDateFormat(template)
      sdf.parse(dateString)
    }
  }

  //定义main方法, 作为程序的主入口.
  def main(args: Array[String]): Unit = {
    //5. 调用DateUtils#date2String()方法, 用来格式化日期.
    val s = DateUtils.date2String(new Date(), "yyyy-MM-dd")
    println("格式化日期: " + s)

    //6. 调用DateUtils#string2Date()方法, 用来解析日期字符串.
    val d = DateUtils.string2Date("1314年5月21日", "yyyy年MM月dd日")
    println("解析字符串: " + d)
  }
}

的单例对象.
object DateUtils {
//2. 创建SimpleDateFormat类型的对象, 用来进行转换操作.
var sdf: SimpleDateFormat = null

//3. 定义方法date2String, 用来将Date日期对象转换成String类型的日期.
//参数1: 日期对象,   参数2: 模板
def date2String(date: Date, template: String):String  = {
  sdf = new SimpleDateFormat(template)
  sdf.format(date)
}

//4. 定义方法string2Date, 用于将String类型的日期转换成Date日期对象.
def string2Date(dateString: String, template: String) = {
  sdf = new SimpleDateFormat(template)
  sdf.parse(dateString)
}

}

//定义main方法, 作为程序的主入口.
def main(args: Array[String]): Unit = {
//5. 调用DateUtils#date2String()方法, 用来格式化日期.
val s = DateUtils.date2String(new Date(), “yyyy-MM-dd”)
println("格式化日期: " + s)

//6. 调用DateUtils#string2Date()方法, 用来解析日期字符串.
val d = DateUtils.string2Date("1314年5月21日", "yyyy年MM月dd日")
println("解析字符串: " + d)

}
}


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

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

相关文章

【Linux指令集】---git命令的基本使用

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【Linux专栏】🎈 本专栏旨在分享学习Linux的一点学习心得,欢迎大家在评论区讨论💌 演示环境&#xff1…

Spring修炼之路(1)基础入门

一、简介 1.1Spring概述 Spring框架是一个轻量级的Java开发框架,它提供了一系列底层容器和基础设施,并可以和大量常用的开源框架无缝集成,可以说是开发Java EE应用程序的必备。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器&…

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真+程序+原理图+报告+讲解视频)

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真程序原理图报告讲解视频) 讲解视频1.主要功能:2.仿真3. 程序代码4.原理图5. 设计报告6. 设计资料内容清单 51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显…

Scala第一章节

Scala第一章节 scala总目录 章节目标 理解Scala的相关概述掌握Scala的环境搭建掌握Scala小案例: 做最好的自己 1. Scala简介 1.1 概述 ​ Scala(斯嘎拉)这个名字来源于"Scalable Language(可伸缩的语言)", 它是一门基于JVM的多范式编程语言, 通俗的说: Scala是一…

面向对象【递归方法】

文章目录 递归编写递归函数递归的工作原理常见的递归应用场景递归注意点 递归 递归是一种解决问题的方法,其中一个函数调用自身以解决较小的实例,直到达到基本情况(停止条件),然后开始返回结果。递归可以让我们更容易地…

CSS详细基础(五)选择器的优先级

本节介绍选择器优先级,优先级决定了元素最终展示的样式~ 浏览器是通过判断CSS优先级,来决定到底哪些属性值是与元素最为相关的,从而作用到该元素上。CSS选择器的合理组成规则决定了优先级,我们也常常用选择器优先级来合理控制元素…

038:vue页面头部提示低版本浏览器升级问题

第038个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 (1)提供vue2的一些基本操作:安装、引用,模板使…

一例疑似MMCore下载器分析

概述 这是一例文件夹病毒,手法相对比较高级,通过域名关联到MMCore样本,可能与印度方向APT组织有关联。 这个病毒使用了分离免杀技术,有2个样本,一个加载器,一个payload。 加载器(文件名为dwm22.exe)的主要…

并发——中断机制

1.中断概述 中断只是一种协商机制,如果要中断一个线程,需要手动调用该线程的interrupt方法,将此线程对象的中断标识设为true(默认中断标志位为false),接着我们需要手动写代码去不断的检测要中断线程的标识位,如果为tr…

阿木实验室PrometheusV1.1安装+Ubuntu 20.04

1. 安装ros-noetic 2. 安装Mavros包 sudo apt-get install ros-noetic-mavros ros-noetic-mavros-extras3. GeographicLib wget https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh这里可以使用代理 :wg…

笔训day1

目录 选择题 1、%m.ns 编程题 第一题 第二题 选择题 1、%m.ns m:字符串的宽度。 n:左起截取目标字符串n个字符,右对齐,补空格。 1、字符串长度>n>m : 受n控制,左起截取n个字符,右对齐&#x…

什么是Times New Roman 字体

如何评价 Times New Roman 字体?:https://www.zhihu.com/question/24614549?sortcreated 新罗马字体是Times New Roman字体,是Office Word默认自带的英文字体之一。 中英文字体 写作中,英文和数字的标准字体为 Times New Roma…

什么是AI客流量算法?如何应用在实际场景中?

客流量分析算法简而言之就是一种利用数据分析和机器学习技术进行人流量统计、预测和分析的算法。它能够根据不同的数据来源,如摄像头、传感器等,对特定区域内的客流量进行实时监测和分析,并通过对历史数据的综合分析,提供客流趋势…

MySQL索引优化,设计原则 及 trace 详解(思维导图)

MySQL版本:8.0.33 MySQL联合索引使用总结:

基于 Python+Django 实现一个电商购物网站系统

随着互联网的高速发展,电子商务行业也正迎来了其黄金时代。如何搭建一个功能完备、体验良好的电商网站成了许多开发者的关心话题。 今天,我将带大家使用Python语言和Django框架,快速打造一个电商购物系统。如果你有一定的Python基础&#xf…

轻松批量重命名:使用编号为文件重新命名,提高工作效率!

如果你经常需要处理大量文件,那么你一定知道给文件重命名是一项多么繁琐的任务。但是,我们今天将为你提供一种简单的方法,可以批量给文件进行重命名,让你轻松提高工作效率 首先我们要进入文件批量改名高手主页面,并在…

px4的gazebo仿真相机模型报错解决办法,返回值256

👉事情起因:我想做关于PX4无人机的摄像头仿真,根据PX4的官网文件 Tools/sitl_gazebo文件夹里面有对应的模型可以使用,我就想在mavros_posix_sitl文件里面修改vehicle参数,比如直接将vehicle“iris_stereo_camera”。然…

C++核心编程--对象篇

4.2、对象 4.2.1、对象的初始化和清理 用于对对象进行初始化设置,以及对象销毁前的清理数据的设置。 构造函数和析构函数 防止对象初始化和清理也是非常重要的安全问题 一个对象或变量没有初始化状态,对其使用后果是未知的同样使用完一个对象或变量&…

【Java 进阶篇】MySQL 多表查询详解

MySQL 是一个强大的关系型数据库管理系统,多表查询是数据库操作中的重要部分之一。多表查询允许您从多个表中检索和操作数据,以满足复杂的数据需求。本文将介绍 MySQL 多表查询的基本概念、语法和示例,以及一些常见的多表查询场景。 什么是多…

PC版企业微信逆向之消息发送CALL-找不到参数文本消息内容,但是确定这就是消息发送CALL

现在遇到的问题是消息内容-如何查看通过esi里面的消息内容,找不到有效的 找不到参数文本消息内容,但是确定这就是消息发送CALL 消息发送call特征码为8d 47 08 50 56 e8 ?? ?? ?? ?? 8b 07 //消息发送CALL如下 **02852932 8B07 mov eax,dword ptr…