Scala面向对象编程(高级部分)

news2025/1/11 12:33:02

1. 静态属性和静态方法

(1)回顾Java中的静态概念

public static 返回值类型 方法名(参数列表) {方法体} 静态属性… 说明:
Java中静态方法并不是通过对象调用的,而是通过类对象调用的,所以静态操作并不是面向对象的。

(2)Scala中静态的概念-伴生对象

①Scala语言是完全面向对象(万物皆对象)的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。也没有static关键字, 但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,我们称之为类的伴生对象。这个类的所有静态内容都可以放置在它的伴生对象中声明和调用
  ②伴生对象的小结

1. Scala中伴生对象采用object关键字声明,伴生对象中声明的全是 "静态"内容,
    可以通过伴生对象名称直接调用。
2. 伴生对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致。
3. 伴生对象中的属性和方法都可以通过伴生对象名直接调用访问    
4. 从语法角度来讲,所谓的伴生对象其实就是类的静态方法和静态变量的集合
5. 从技术角度来讲,scala还是没有生成静态的内容,只不过是将伴生对象生成了一个新的类,
    实现属性和方法的调用。
6. 从底层原理看,伴生对象实现静态特性是依赖于 public static final MODULE$ 实现的。
7. 伴生对象的声明应该和伴生类的声明在同一个源码文件中(如果不在同一个文件中会运行错误!),
    但是如果没有伴生类,也就没有所谓的伴生对象了,所以放在哪里就无所谓了。
8. 如果 class A 独立存在,那么A就是一个类, 如果 object A 独立存在,那么A就是一个"
静态"性质的对象[即类对象], 在 object A中声明的属性和方法可以通过 A.属性 和 A.方法
来实现调用

(3)伴生对象apply方法

在伴生对象中定义apply方法,可以实现: 类名(参数) 方式来创建对象实例.

class Child private (var name: String, var age: Int, var address: String) {
Child.nums += 1
}
object Child {
var nums: Int = _
// apply方法会通过类(实参列表)调用到
def apply(name: String, age: Int, address: String): Child = {
println("apply()...")
new Child(name, age, address)
}
}

object Test {
def main(args: Array[String]): Unit = {
//加入apply方法后可以将主构造器加上private修饰,这样就
//只能通过apply方法调用来生成对象了
//val child1 = new Child("小花1", 10, "昌平")
//println(child1.name)
val array1 = new Array[Int](8)
val array2 = Array(1, 3, 8, 7)

val child2 = Child("小明", 5, "朝阳")// 自动调用apply方法
println(child2.name)
}
}

2. 单例模式

定义:保证在整个的软件系统中,某个类只能存在一个对象实例。
应用场景:

比如Hibernate的SessionFactory,它充当数据存储源的代理,并负责创建Session对象。SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够,这是就会使用到单例模式。
Akka [ActorySystem 单例] AKKA

Scala中没有静态的概念,所以为了实现Java中单例模式的功能,可以直接采用类对象(即伴生对象)方式构建单例对象

方式一:懒汉式

object TestSingleTon extends App{
val singleTon = SingleTon.getInstance
val singleTon2 = SingleTon.getInstance
println(singleTon.hashCode() + " " + singleTon2.hashCode())
}
//将SingleTon的构造方法私有化
class SingleTon private() {}

object SingleTon {
private var s:SingleTon = null
def getInstance = {
if(s == null) {
s = new SingleTon
}
s
}
}
object TestSingleTon extends App {
val singleTon = SingleTon.getInstance
val singleTon2 = SingleTon.getInstance
println(singleTon.hashCode() + " ~ " + singleTon2.hashCode())
println(singleTon == singleTon2)
}
//将SingleTon的构造方法私有化
class SingleTon private() {
println("~~~")
}
object SingleTon {
private val s: SingleTon = new SingleTon
def getInstance = {
s
}
}
//说明:饿汉式

3.接口

(1)回顾Java接口

声明接口
   interface 接口名
实现接口
   class 类名 implements 接口名1,接口2
(1)在Java, 一个类可以实现多个接口。
(2)在Java中,接口之间支持多继承
(3)接口中属性都是常量
(4)接口中的方法都是抽象的

(2)Scala接口的介绍

从面向对象来看,接口并不属于面向对象的范畴,Scala是纯面向对象的语言,在Scala中,没有接口, 也没有implements关键字。Scala语言中,采用trait(特质,特征)来代替接口的概念,也就是说,多个类具有相同的特征(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。

(3)特质

trait 的声明
    trait 特质名 {
       trait体
     }**

trait 命名 一般首字母大写. Cloneable , Serializable
object T1 extends object T1 extends Serializable { } ,其中 Serializable 就是scala的一个特质。
在scala中,java中的接口可以当做特质使用

一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,所以在使用时,也采用了extends关键字,如果有多个特质或存在父类,那么需要采用with关键字连接

没有父类:
    class 类名 extends 特质1 with 特质2 with 特质3 ..
有父类 :
   class 类名 extends 父类 with 特质1 with 特质2 with 特质3

(4)特质的再说明

Scala提供了特质(trait),特质可以同时拥有抽象方法和具体方法,一个类可以实现/继承多个特质。
特质中没有实现的方法就是抽象方法。类通过extends继承特质,通过with可以继承多个特质
所有的java接口都可以当做Scala特质使用

abstract class Pet(var name:String, var age: Int, var weight: Double) {
var id: Int // 抽象的属性
// 普通方法
// 抽象方法, 没有=和方法体
def eat
override def toString(): String = {
name + "," + age + "," + weight
}
}
class Dog extends Pet("小黄", 2, 2.5) {
    // Pet(实参列表)作用是调用父类构造器,完成属性的初始化
var id = 20
override def eat = println("吃狗粮")
     // 如果是方法的实现, 可以省略override
def kanjia(): Unit = {
println("看家狗")
}
}
class Bird(name:String, age: Int, weight: Double)
                        extends Pet(name, age, weight) {
var id = 30
def eat = println("吃虫子")
}

object PetTest {
def main(args: Array[String]): Unit = {
//new Pet("小黑", 2, 20)
val dog = new Dog
val bird = new Bird("小飞", 1, 0.2)
println(dog)
println(bird)

var v : Pet = new Dog() // 多态
v = bird
//((Dog)v).kanjia
if (v.isInstanceOf[Dog]) {
v.asInstanceOf[Dog].kanjia // 造型
}
}
}

(5)带有特质的对象:动态混入
1.除了可以在类声明时继承特质以外,还可以在构建对象时混入特质,扩展对象的功能
2.此种方式也可以应用于对抽象类功能进行扩展
3.动态混入是Scala特有的方式(java没有动态混入),可在不修改类声明/定义的情况下,扩展类的功能,非常的灵活,耦合性低 。
4.动态混入可以在不影响原有的继承关系的基础上,给指定的类扩展功能。

//写一个特质Flyer, 写两个抽象方法takeOff, fly, 具体方法land
trait Flyer {
var name:String // 这是抽象属性, 在特质中变成抽象方法
var speed: Int = 2000 // 普通属性, 在特质中变成抽象方法

def takeOff():Unit
def fly
def land = println("我要着陆了....")
}
//写一个子类Plane, 再混入其他特质 with后面只允许特质, extends后面可以是特质也可以是类
//在类中使用with是静态混入, 只要创建本类对象,都具备这些特质
class Plane extends Flyer with Serializable with Comparable[Plane] {
var name = "大飞机" // 覆盖属性
// 在子类中重新定义
// 特质中的普通属性, 在子类中也仍然需要重新定义, 提供了set方法, 会被特质的特殊类调用.
def takeOff(): Unit = println("飞机起飞中, 推背感强")
override def fly: Unit = println("平稳飞行中...")
override def compareTo(o: Plane) = 0
}

class Man {
type T
}

class Chinese extends Man {
override type T = String
}
class English extends Man {
override type T = Double
}

object TraitExer {

def main(args: Array[String]): Unit = {
type P = Plane
var p: P = new P
println(p)
p.fly
}

def main3(args: Array[String]): Unit = {
val man1 = new Man
// 在创建对象时使用with特质, 也可以实现混入,称为动态混入, 混入的特质只对当前对象有效
val man2 = new Man with Flyer with Serializable {
var name = "abc"
override def takeOff(): Unit = println("不知怎么就会飞了")
override def fly: Unit = println("引力对我没用")
}
man2.fly

val man3 = new Man{} // 匿名内部类

}

def main2(args: Array[String]): Unit = {
val plane = new Plane
plane.takeOff()
plane.land

val flyer2 = new Flyer {
var name = "yyy"
override def takeOff(): Unit = println("lll")
override def fly: Unit = println("fly")
}

}
}

(6)叠加特质
构建对象的同时如果混入多个特质,称之为叠加特质,那么特质声明顺序从左到右,方法执行顺序从右到左。

trait Operate4 {
println("Operate4...")
def insert(id : Int)
}
trait Data4 extends Operate4 {
println("Data4")
override def insert(id : Int): Unit = {
println("插入数据 = " + id)
}
}
trait DB4 extends Data4 {
println("DB4")
override def insert(id : Int): Unit = {
print("向数据库")
super.insert(id)
}
}
trait File4 extends Data4 {
println("File4")
override def insert(id : Int): Unit = {
print("向文件")
super.insert(id)
}}
class MySQL4 {}
// 1.Scala在叠加特质的时候,会首先从后面的特质开始执行
// 2.Scala中特质中如果调用super,并不是表示调用父特质的方法,而是向前面(左边)继续查找特质,如果找不到,才会去父特质查找
val mysql = new MySQL4 with DB4 with File4
//val mysql = new MySQL4 with File4 with DB4
mysql.insert(888)

上述程序执行结果为:

Operate4...
Data4
DB4
File4
向文件向数据库插入数据 = 888

debug整个过程发现,最后一行程序执行时先到了trait File4中的insert方法,然后又去了DB4的insert方法,最后去了Data4的insert方法,执行打印语句完毕后按逆顺序出栈

叠加特质
叠加特质注意事项和细节
1.特质声明顺序从左到右。
2.Scala在执行叠加对象的方法时,会首先从后面的特质(从右向左)开始执行
3.Scala中特质中如果调用super,并不是表示调用父特质的方法,而是向前面(左边)继续查找特质,如果找不到,才会去父特质查找
4.如果想要调用具体特质的方法,可以指定:super[特质].xxx().其中的泛型必须是该特质的直接超类类型

将上述程序中Trait File 改为以下内容:

trait File4 extends Data4 {
println("File4")
override def insert(id : Int): Unit = {
print("向文件")
super[Data4].insert(id)
}
}

此时执行结果为:

Operate4...
Data4
DB4
File4
向文件插入数据 = 888

(7)在特质中重写抽象方法
方式1 : 去掉 super()…
方式2: 调用父特质的抽象方法,那么在实际使用时,没有方法的具体实现,无法编译通过,为了避免这种情况的发生。可重写抽象方法,这样在使用时,就必须考虑动态混入的顺序问题。

理解 abstract override 的小技巧分享:可以这里理解,当我们给某个方法增加了abstract override
后,就是明确的告诉编译器,该方法确实是重写了父特质的抽象方法,但是重写后,该方法仍然是一个抽象方法(因为没有完全的实现,需要其它特质继续实现[通过混入顺序])

trait Operate5 {
def insert(id : Int)
}
trait File5 extends Operate5 {
abstract override def insert( id : Int ): Unit = {
println("将数据保存到文件中..")
super.insert(id)
}
}

trait DB5 extends Operate5 {
def insert( id : Int ): Unit = {
println("将数据保存到数据库中..")
}
}
class MySQL5 {}
val mysql5 = new MySQL5 with DB5 with File5

重写抽象方法时需要考虑混入特质的顺序问题和完整性问题 看4个案例,并判断结果。
var mysql2 = new MySQL5 with DB5 // ok
mysql2.insert(100)
var mysql3 = new MySQL5 with File5 // error
mysql2.insert(100)
var mysql4 = new MySQL5 with File5 with DB5// error
mysql4.insert(100)
var mysql4 = new MySQL5 with DB5 with File5// ok
mysql4.insert(100)

富接口概念:即该特质中既有抽象方法,又有非抽象方法

trait Operate {
def insert( id : Int ) //抽象
def pageQuery(pageno:Int, pagesize:Int): Unit = { //实现
println("分页查询")
}
}

特质中的具体字段

特质中可以定义具体字段,如果初始化了就是具体字段,如果不初始化就是抽象字段。混入该特质的类就具有了该字段,字段不是继承,而是直接加入类,成为自己的字段。

特质中的抽象字段

特质中未被初始化的字段在具体的子类中必须被重写。

特质构造顺序

特质也是有构造器的,构造器中的内容由“字段的初始化”和一些其他语句构成。具体实现请参考“特质叠加”

第一种特质构造顺序(声明类的同时混入特质)
调用当前类的超类构造器
第一个特质的父特质构造器
第一个特质构造器
第二个特质构造器的父特质构造器, 如果已经执行过,就不再执行
第二个特质构造器
…重复4,5的步骤(如果有第3个,第4个特质)
当前类构造器
第2种特质构造顺序(在构建对象时,动态混入特质)
调用当前类的超类构造器
当前类构造器
第一个特质构造器的父特质构造器
第一个特质构造器.
第二个特质构造器的父特质构造器, 如果已经执行过,就不再执行
第二个特质构造器
…重复5,6的步骤(如果有第3个,第4个特质)
当前类构造器
分析两种方式对构造顺序的影响
第1种方式实际是构建类对象, 在混入特质时,该对象还没有创建。
第2种方式实际是构造匿名子类,可以理解成在混入特质时,对象已经创建了。

扩展类的特质

特质可以继承类,以用来拓展该类的一些功能(和java的不同)

trait LoggedException extends Exception{
def log(): Unit ={
println(getMessage()) // 方法来自于Exception类
}
}

所有混入该特质的类,会自动成为那个特质所继承的超类的子类

trait LoggedException extends Exception{
def log(): Unit ={
println(getMessage()) // 方法来自于Exception类
}
}
//UnhappyException 就是Exception的子类.
class UnhappyException extends LoggedException{
// 已经是Exception的子类了,所以可以重写方法
override def getMessage = "错误消息!"
}

如果混入该特质的类,已经继承了另一个类(A类),则要求A类是特质超类的子类,否则就会出现了多继承现象,发生错误。

自身类型

自身类型(self-type):主要是为了解决特质的循环依赖问题,同时可以确保特质在不扩展某个类的情况下,依然可以做到限制混入该特质的类的类型。
应用案例举例说明自身类型特质,以及如何使用自身类型特质

//Logger就是自身类型特质
trait Logger {
// 明确告诉编译器,我就是Exception,如果没有这句话,下面的getMessage不能调用
this: Exception =>
def log(): Unit ={
// 既然我就是Exception, 那么就可以调用其中的方法
println(getMessage)
}
}

4. type关键字

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

type S = String
var v : S = “abc”
def test() : S = “xyz”

5. 嵌套类

在Scala中,你几乎可以在任何语法结构中内嵌任何语法结构。如在类中可以再定义一个类,这样的类是嵌套类,其他语法结构也是一样。
嵌套类类似于Java中的内部类。

public class TestJavaClass {
public static void main(String[] args) {
//创建一个外部类对象
OuterClass outer1 = new OuterClass();
//创建一个外部类对象
OuterClass outer2 = new OuterClass();
// 创建Java成员内部类
// 说明在Java中,将成员内部类当做一个属性,因此使用下面的方式来创建 outer1.new InnerClass().
OuterClass.InnerClass inner1 = outer1.new InnerClass();
OuterClass.InnerClass inner2 = outer2.new InnerClass();

//下面的方法调用说明在java中,内部类只和类型相关,也就是说,只要是
//OuterClass.InnerClass 类型的对象就可以传给 形参 InnerClass ic
inner1.test(inner2);
inner2.test(inner1);

// 创建Java静态内部类
// 因为在java中静态内部类是和类相关的,使用 new OuterClass.StaticInnerClass()
OuterClass.StaticInnerClass staticInner = new OuterClass.StaticInnerClass();
}}
class OuterClass { //外部类
class InnerClass { //成员内部类
public void test( InnerClass ic ) {
System.out.println(ic);
}}

static class StaticInnerClass { //静态内部类
}}

scala嵌套类的使用1:

class ScalaOuterClass {
class ScalaInnerClass { //成员内部类
}
}
object ScalaOuterClass { //伴生对象
class ScalaStaticInnerClass { //静态内部类
}
}
val outer1 : ScalaOuterClass = new ScalaOuterClass();
val outer2 : ScalaOuterClass = new ScalaOuterClass();

// Scala创建内部类的方式和Java不一样,将new关键字放置在前,使用 对象.内部类 的方式创建
val inner1 = new outer1.ScalaInnerClass()
val inner2 = new outer2.ScalaInnerClass()
//创建静态内部类对象
val staticInner = new ScalaOuterClass.ScalaStaticInnerClass()
println(staticInner)

scala嵌套类的使用2:

请编写程序,在内部类中访问外部类的属性和方法两种方法。
方式一:

class ScalaOuterClass {
var name : String = "scott"
private var sal : Double = 1.2
class ScalaInnerClass { //成员内部类
def info() = {
// 访问方式:外部类名.this.属性名
// 怎么理解 ScalaOuterClass.this 就相当于是 ScalaOuterClass
        这个外部类的一个实例,
// 然后通过 ScalaOuterClass.this 实例对象去访问 name 属性
// 只是这种写法比较特别,学习java的同学可能更容易理解
         ScalaOuterClass.class 的写法.
println("name = " + ScalaOuterClass.this.name
+ " age =" + ScalaOuterClass.this.sal)
}
}
}
object ScalaOuterClass { //伴生对象
class ScalaStaticInnerClass { //静态内部类
}
}
//调用成员内部类的方法
inner1.info()

方式二:
内部类如果想要访问外部类的属性,也可以通过外部类别名访问(推荐)。即:访问方式:外部类名别名.属性名 【外部类名.this 等价 外部类名别名】

class ScalaOuterClass {
myOuter => //这样写,你可以理解成这样写,myOuter就是代表外部类的一个对象.
class ScalaInnerClass { //成员内部类
def info() = {
println("name = " + ScalaOuterClass.this.name
+ " age =" + ScalaOuterClass.this.sal)
println("-----------------------------------")
println("name = " + myOuter.name
+ " age =" + myOuter.sal)
}}
// 当给外部指定别名时,需要将外部类的属性放到别名后.
var name : String = "scott"
private var sal : Double = 1.2
}

object ScalaOuterClass { //伴生对象
class ScalaStaticInnerClass { //静态内部类
}
}
inner1.info()类型投影
先看一段代码,引出类型投影


class ScalaOuterClass3 {
myOuter =>
class ScalaInnerClass3 { //成员内部类
def test(ic: ScalaInnerClass3): Unit = {
System.out.println(ic)
}
}
}

分析以下代码正确/错误:

object Scala01_Class {
    def main(args: Array[String]): Unit = {
        val outer1 : ScalaOuterClass3 = new ScalaOuterClass3();
        val outer2 : ScalaOuterClass3 = new ScalaOuterClass3();
        val inner1 = new outer1.ScalaInnerClass3()
        val inner2 = new outer2.ScalaInnerClass3()
        inner1.test(inner1) // ok
        inner1.test(inner2) // error 原因是scala内部类对象和外部类对象相关.
        //这时可以使用类型投影来屏蔽类型不同
}
}

解决方式-使用类型投影
类型投影是指:在方法声明上,如果使用 外部类#内部类 的方式,表示忽略内部类的对象关系,等同于Java中内部类的语法操作,我们将这种方式称之为 类型投影(即:忽略对象的创建方式,只考虑类型)

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

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

相关文章

SpringBoot 统一异常处理

1. 统一返回结果集 package com.liming.pojo;import com.liming.exception.AppExceptionCodeMsg; import lombok.Data;/*** 全局统一返回结果类* author 黎明* date 2023/9/6 14:11* version 1.0*/ Data public class Result<T> {private Integer code; // 状态码privat…

C#模拟PLC设备运行

涉及&#xff1a;控件数据绑定&#xff0c;动画效果 using System; using System.Windows.Forms;namespace PLCUI {public partial class MainForm : Form{ public MainForm(){InitializeComponent();}private void MainForm_Load(object sender, EventArgs e){// 方式2&#x…

基于SpringBoot的校园失物招领系统

基于SpringBooVuet的校园失物招领系统&#xff0c;前后端分离 附万字文档 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 角色&#xff1a;管理员、用户 管理员  …

线性空间、子空间、基、基坐标、过渡矩阵

线性空间的定义 满足加法和数乘封闭。也就是该空间的所有向量都满足乘一个常数后或者和其它向量相加后仍然在这个空间里。进一步可以理解为该空间中的所有向量满足加法和数乘的组合封闭。即若 V 是一个线性空间&#xff0c;则首先需满足&#xff1a; 注&#xff1a;线性空间里面…

AR工业远程巡查系统:实时监控设备状态,及时发现潜在问题

随着工业4.0的到来&#xff0c;先进的技术和创新的解决方案正在改变着工业生产的方式。其中&#xff0c;增强现实&#xff08;AR&#xff09;技术带来的工业巡检系统就是一个典型的例子。这种系统通过在现实世界中添加虚拟信息&#xff0c;使得操作人员能够更有效地进行检查和维…

leetcode 1002. 查找共用字符

2023.9.6 个人感觉这题难度不止简单&#xff0c;考察到的东西还是挺多的。 首先理解题意&#xff0c;可以将题意转化为&#xff1a;求字符串数组中 各字符串共同出现的字符的最小值。 分为三步做&#xff1a; 构造一个哈希表hash&#xff0c;初始化第一个字符串的字母出现频率…

2020年12月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;字符三角形 描述 给定一个字符&#xff0c;用它构造一个底边长5个字符&#xff0c;高3个字符的等腰字符三角形。 输入 输入只有一行&#xff0c; 包含一个字符。 输出 该字符构成的等腰三角形&#xff…

Zookeeper简述

数新网络-让每个人享受数据的价值 官网现已全新升级—欢迎访问&#xff01; 前 言 ZooKeeper是一个开源的、高可用的、分布式的协调服务&#xff0c;由Apache软件基金会维护。它旨在帮助管理和协调分布式系统和应用程序&#xff0c;提供了一个可靠的平台&#xff0c;用于处理…

苹果与芯片巨头Arm达成20年新合作协议,将继续采用芯片技术

9月6日消息&#xff0c;据外媒报道&#xff0c;芯片设计巨头Arm宣布在当地时间周二提交给美国证券交易委员会&#xff08;SEC&#xff09;的最新IPO文件中&#xff0c;透露与苹果达成了一项长达20年的新合作协议&#xff0c;加深了双方之间的合作关系。 报道称&#xff0c;虽然…

Informatica使用操作流程及Expression(表达式转换)案例2

操作流程 ①定义源<Odbc01_oracle:employees> ②定义目标<EDW_EMPLOYEES> ③创建映射<M_ORACLE_EDW01_employees> ④定义任务<S_ORCL_EDW01_employees> ⑤创建工作流<W_ORCL_EDW01_employees> ⑥工作流调度监控 ⑦查验数据 一、需求&…

js---16-----JavaScript中的类型转换机制

、类型转换机制是什么&#xff1f; JS中有六种简单数据类型&#xff1a;undefined、null、bollean、string、number、symbol&#xff0c;以及引用类型object 但是我们声明的时候只有一种数据类型&#xff0c;只用运行期间才会确定当前类型。 上面代码中&#xff0c;x的值在编…

浅谈redis未授权漏洞

redis未授权漏洞 利用条件 版本比较高的redis需要修改redis的配置文件&#xff0c;将bind前面#注释符去掉&#xff0c;将protected-mode 后面改为no 写入webshell config get dir #查看redis数据库路径 config set dir web路径# #修改靶机Redis数据库路径 config set dbfilen…

巧用抽象类与接口,打造高效Java程序(上)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:《C语言入门知识》&#x1f649; &#x1f649; 内容推荐:&#x1f649; &#x1f439;今日诗词:十年花骨东风泪&#xff0c;几点螺香素壁尘&#x1f439; 目录 &#x1f338;思维导图&#x1f338; &#x1f338;…

怎么做加密文件二维码?简单技巧快速做二维码

怎么做一个加密的文件二维码呢&#xff1f;现在将文件做成二维码来传递是一种很常见的方式&#xff0c;那么为了保证文件不会被私自下载&#xff0c;那么如何在将文件生成二维码的时候&#xff0c;给二维码进行加密设置呢&#xff1f;下面就让小编给大家分享一下二维码生成器在…

【C\C++】内存分配 和 动态内存管理方式

文章目录 内存分类题目&#xff1a;知识巩固选择题: 变量位于内存中的位置计算题 变量值的大小 答案 C语言 动态内存管理malloc / calloc / realloc作用区别 C 内存管理方式operator new 与 operator deletenew 与 delete 的实现原理malloc free 与 new delete 的区别 内存泄漏…

MySql 变量

1.系统变量 1.1 系统变量分类 变量由系统定义&#xff0c;不是用户定义&#xff0c;属于 服务器 层面。系统变量分为全局系统变量&#xff08;需要添加 global 关键字&#xff09;以及会话系统变量&#xff08;需要添加 session 关键字&#xff09;&#xff0c;有时也把全局系…

mysql UUID 作为主键的问题

UUID 在MySQL中&#xff0c;可以使用UUID()函数来生成一个新的UUID值。该函数的返回值是一个字符串类型&#xff0c;表示一个32位的十六进制数字&#xff0c;其中包含4个连字符“-”&#xff0c;例如&#xff1a;“6ccd780c-baba-1026-9564-0040f4311e29”。 varchar(32) 32*4…

【免费模板】2023数学建模国赛word+latex模板免费分享

无需转发 免费获取2023国赛模板&#xff0c;获取方式见文末 模板文件预览如下&#xff1a; 模板参考格式如下&#xff1a; &#xff08;题目&#xff09;XXXXXX 摘 要&#xff1a; 开头段&#xff1a;需要充分概括论文内容&#xff0c;一般两到三句话即可&#xff0c;长度控…

Java基础二十五(Map)

Map 接口 Map 接口是 Java 集合框架中的一种用于储存键值对映射关系的接口。Map 接口提供了一种通过键来访问值的方式&#xff0c;其中每一个键都是唯一的&#xff0c;值可以重复。 public interface Map<K,V>Map 接口的主要特征如下&#xff1a; 键唯一性&#xff1a;…

matlab数据处理: cell table array+datetime

原数据文件.csv matlab xlsread(filename{i},B2:T2881) 会同于Excel最多1048576行 舍弃 a{1,i} xlsread(filename{i},‘B2:T2881’);%读取excel文件,选定区域’B2:G2881’ readcell(filename{i},Range,E2:M2881) 会全部读取 优选 对于日期 yyyy-MM-dd HH:mm:ss.000 matlab cel…