C++三大特性之继承,详细介绍

eea5eba81baa42f0a333f323d0825d11.jpeg

阿尼亚全程陪伴大家学习~

前言

每个程序员在开发新系统时,都希望能够利用已有的软件资源,以缩短开发周期,提高开发效率。 为了提高软件的可重用性(reusability),C++提供了类的继承机制。

1.继承的概念

继承: 指在现有类的基础上建立一个新的类。现有类称为基类或父类,新建类称为派生类或子类。对于父类与子类,人们也常说子类继承了父类,或者父类派生了子类。

语法:class 子类(派生类):继承方式 父类(基类)

现在我们一起来看一下具体的实现

#include<iostream>
using namespace std;
//基础界面
class BasePage
{
	void left()
	{
		cout << "Java,C++,Python,C...." << endl;
	}
	void right()
	{
		cout << "右界面" << endl;
	}
	void head()
	{
		cout << "头部界面" << endl;
	}
	void bottom()
	{
		cout << "底部界面" << endl;
	}
};
//C语言界面
class C 
{
public:
	void left()
	{
		cout << "Java,C++,Python,C...." << endl;
	}
	void right()
	{
		cout << "右界面" << endl;
	}
	void head()
	{
		cout << "头部界面" << endl;
	}
	void bottom()
	{
		cout << "底部界面" << endl;
	}
	void Linux()
	{
		cout << "Linux" << endl;
	}
};
//C语言界面
class C :public BasePage
{
public:
	void Linux()
	{
		cout << "Linux" << endl;
	}
};
//Java界面
class Java :public BasePage
{
public:
	void JavaSE()
	{
		cout << "JavaSE" << endl;
	}
};

这可以看做一个编程语言学习的主界面,左界面是各种不同语言的分类,这些不同编程语言界面都有主界面的部分,但是他们也有自己独特的部分,主界面是基类,而具体的编程语言界面则是派生类,派生类都继承了父类(基类)所有的成员函数。

2.继承的三种方式

公共(public)继承、保护(protected)继承、私有(private)继承

57b776b97a5a42bf9c40a65b14817fb2.png

下面我们一一介绍

2.1公共继承

#include<iostream>
using namespace std;
class A
{
private:
	int _a = 1;
public:
	int _A = 10;
	void A_print()
	{
		cout << "_a=" << _a << endl;
		cout << "_A=" << _A << endl;
	}
};
class B:public A
{
private:
	int _b = 2;
public:
	int _B = 20;
	void B_print()
	{
		cout << "_b=" << _b << endl;
	}
};
int main()
{
	B b;
	b.B_print();
	b.A_print();
	return 0;
}

72cd08d60b8e425db7cd1497424a84ff.png

我们发现通过公共继承的方式来继承A类,A类中的打印函数也被继承了,所以B类的对象可以调用A类的成员函数,接下来我们修改一下代码,在B类中访问A类的成员变量

9a012076321d43a9a05e0e9aa25d89ee.png

93a2f026724b48519b3e5c6244457f70.png

编译器告诉我们_a不可以被访问因为他是A类中的私有成员,而_A可以被访问因为他是A类中的公有成员,那有没有什么方法能让_a也能被访问呢?

有。一种是把_a设置为public成员,另外一种是把_a设置为protected成员(最好的做法),这三种又有什么区别呢?(重要!!!)

*公有(public)成员:

公有成员可以从任何地方被访问,包括类的内部、类的派生类以及类的外部。
把_a设置为公有成员意味着任何地方的代码都可以直接访问它,这通常不是一个好的做法,因为它破坏了封装性(封装性意味着隐藏对象的内部状态以防止它们被外部代码直接访问)。

*私有(private)成员:

私有成员只能在类的内部被访问。
编译器告诉我们_a不可以被访问,因为它被声明为私有成员。这意味着你不能从类的外部或派生类中直接访问它。

*保护(protected)成员:

保护成员可以在类的内部和派生类中被访问,但不能在类的外部被访问。
把_a设置为保护成员意味着你可以在其派生类中访问它,但不能在类的外部直接访问它。这提供了一种在派生类中重用和扩展基类功能的方式,同时保持对外部世界的封装性。

能明白三者的差异,也就很容易理解三种继承方式的差别了

#include<iostream>
using namespace std;
class A
{
private:
	int _a = 1;
protected:
	int a = 100;
public:
	int _A = 10;
	void A_print()//A类打印函数
	{
		cout << "_a=" << _a << endl;
		cout << "_A=" << _A << endl;
		cout << "a=" << a << endl;
	}
};
class B:public A
{
private:
	int _b = 2;
public:
	void B_print()//B类打印函数
	{
		cout << "_b=" << _b << endl;

		//cout << "_a=" << _a << endl;//A类私有成员不能被访问
		cout << "_A=" << _A << endl;//A类公有成员可以被访问
		cout << "a=" << a << endl;//A类保护成员可以被访问

		A_print();//A类公有成员可以被访问
	}
};
int main()
{
	B b;
	b.B_print();
	cout << endl;

	cout << b._A << endl;//public继承方式,在类的外部能访问类public成员
	b.A_print();//public继承方式,在类的外部能访问类public成员
	
	//cout << b.a << endl;//在类的外部不能访问类protected成员
	return 0;
}

2.2保护继承

#include<iostream>
using namespace std;
class A
{
private:
	int _a = 1;
protected:
	int a = 100;
public:
	int _A = 10;
	void A_print()//A类打印函数
	{
		cout << "_a=" << _a << endl;
		cout << "_A=" << _A << endl;
		cout << "a=" << a << endl;
	}
};
class B:protected A
{
private:
	int _b = 2;
public:
	void B_print()//B类打印函数
	{
		cout << "_b=" << _b << endl;

		//cout << "_a=" << _a << endl;//A类私有成员不能被访问
		cout << "_A=" << _A << endl;//A类公有成员可以被访问
		cout << "a=" << a << endl;//A类保护成员可以被访问

		A_print();//A类公有成员可以被访问
	}
};
int main()
{
	B b;
	b.B_print();
	//b.A_print();//protected继承方式,在类的外部不能访问类成员
	return 0;
}

 

2e7f28a743fa4e6d8669fa810f6e06ac.png

2.3私有继承

#include<iostream>
using namespace std;
class A
{
private:
	int _a = 1;
protected:
	int a = 100;
public:
	int _A = 10;
	void A_print()//A类打印函数
	{
		cout << "_a=" << _a << endl;
		cout << "_A=" << _A << endl;
		cout << "a=" << a << endl;
	}
};
class B:private A
{
private:
	int _b = 2;
public:
	void B_print()//B类打印函数
	{
		cout << "_b=" << _b << endl;

		//cout << "_a=" << _a << endl;//A类私有成员不能被访问
		cout << "_A=" << _A << endl;//A类公有成员可以被访问
		cout << "a=" << a << endl;//A类保护成员可以被访问

		//A_print();//A类公有成员可以被访问
	}
};
int main()
{
	B b;
	b.B_print();
	cout << endl;
	//cout << b._A << endl;//private继承方式,在类的外部不能访问类public成员
	//cout << b.a << endl;private继承方式,在类的外部不能访问类protected成员
	//b.A_print();//private继承方式,在类的外部不能访问类public成员
	return 0;
}

d7137cceb740440b8e3327a29eff7c2f.png

总结

在类的内部,派生类无论是以哪种方式继承基类,都不能访问基类的private成员,而基类的public成员、protected成员可以被派生类访问

在类的外部,首先需要明确的是无论是基类还是派生类的private成员和protected成员都是不能直接被访问的。而public继承的方式可以通过派生类的对象访问基类的public成员,而private继承的方式和protected继承的方式中,却不可以通过派生类的对象访问基类的public成员(可以这么理解此时基类的public成员分别成了派生类的私有成员和保护成员)

下图辅助理解

229a0b6d10214a0293e3da56fc85412c.png

61b3089280d344f7b93ebc88013aeebc.png

3.继承的对象模型

718f57d5558447ff9c44c839bc476a4c.png

我们发现B类的大小是16个字节,但是我们之前继承方式当中不是说基类的私有成员派生类不能访问吗?

其实父类中所有非静态成员都会被子类继承,父类中的私有成员属性其实是被编译器隐藏了,因此访问不到,但是确实被继承了下来,下面我们来验证一下

首先我们先打开这个工具(开发人员命令提示符)

613ae8d3be7d47468f5014d2bd15da21.png

指令输入步骤

c5e6a59d0159496aa4ac63dc2c785674.png

最终呈现结果

ca3ffc87bc904cbcab43d77949454264.png

经过验证是不是更可靠了呢

4.派生类的构造函数和析构函数

4.1构造函数

派生类不继承基类的构造函数,在声明派生类时一般应定义自己的构造函数db9b43127fe74ab58bb63cad00b80c4a.png

注意

派生类构造函数的总参数表中的参数,应当包括调用基类构造函数所需的参数 派生类构造函数的执行过程是,先调用基类构造函数初始化基类成员,然后对新增成员初始化

#include<iostream>
#include<string>
using namespace std;

class Person//基类
{
protected:
	string _name;//姓名
	char _sex;//性别
	int _age;//年龄
public:
	//Person构造函数
	Person(string name,char sex,int age)
	:_name(name)
	,_sex(sex)
	,_age(age){}
	void PersonPrint()
	{
		cout << "name:" << _name << endl;
		cout << "sex:" << _sex << endl;
		cout << "age:" << _age << endl;
	}
};
//派生类
class Student :public Person
{
private:
	int _num;//学号
public:
	//Student构造函数
	Student(string name,char sex,int age,int num)
	:Person(name,sex,age),_num(num)
	{}
	void StudentPrint()
	{
		PersonPrint();
		cout << "num:" << _num << endl;
	}
};
int main()
{
	Student s("liming", 'M', 18, 1001);
	s.StudentPrint();
	return 0;
}

0e4eca5fe1384ebfac822be5744e520e.png

4.1.1有子对象的派生类的构造函数

在学习结构体时,我们讲到一个结构体的成员还可以是个结构体变量。 派生类也可以有子对象(类类型的成员变量)

d022ad16d4204a1784e9c59e36e682c3.png

#include<iostream>
#include<string>
using namespace std;

class Person//基类
{
protected:
	string _name;//姓名
	char _sex;//性别
	int _age;//年龄
public:
	//Person构造函数
	Person(string name,char sex,int age)
	:_name(name)
	,_sex(sex)
	,_age(age){}
	void PersonPrint()
	{
		cout << "name:" << _name << endl;
		cout << "sex:" << _sex << endl;
		cout << "age:" << _age << endl;
	}
};
//派生类
class Student :public Person
{
private:
	Person _teacher;//班主任(子对象)
	int _num;//学号
public:
	//Student构造函数
	Student(string name,char sex,int age,int num,const Person& teacher)
	:Person(name,sex,age),_num(num),_teacher(teacher)
	{}
	void StudentPrint()
	{
		PersonPrint();//打印学生的信息
		cout << "num:" << _num << endl;
		_teacher.PersonPrint();//打印老师的信息
	}
};
int main()
{
	Person teacher("zhaoli", 'F', 38);//班主任
	Student s("liming", 'M', 18, 1001, teacher);//学生
	s.StudentPrint();
	return 0;
}

5f8537b22c4d4a9685933a5698270833.png

基类构造函数和子对象的书写顺序可以任意

这里有子对象的派生类的构造函数还有另外两种写法

写法一

这种不如引用传参更安全,效率高

e5f8dd2afd1d4aee805a8f580180ecd6.png

写法二

这种写法相对比较麻烦,写的形参更多了

919d454d00094125ad877a5ca1a79b77.png

4.1.2派生类构造函数的执行顺序

结论:

先调用基类构造函数,对基类数据成员初始化

再调用子对象类的构造函数,对子对象的数据成员初始化

最后执行派生类构造函数体中的语句,对派生类新增数据成员初始化

验证

4a11cf824b454f17b58aa4f654f5c23b.png

4.2析构函数

1.派生类不继承基类的析构函数,在声明派生类时,应当定义自己的析构函数

2.派生类的析构函数只对新增成员进行清理工作,基类、子对象的清理工作仍由它们各自的析构函数负责。

3.在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,分别对基类和子对象进行清理

4.析构函数的执行顺序与构造函数正好相反 先执行派生类自己的析构函数,对派生类新增成员进行清理; 然后调用子对象的析构函数,对子对象进行清理; 最后调用基类的析构函数,对基类进行清理。

析构顺序验证

3c98b196292840a9b1421176e8e4185f.png

我们发现Person类只构造了两次,居然析构了三次,这是为什么呢?

其实是因为默认的Person类拷贝构造函数,现在我们显示写一下他的拷贝构造函数来验证一下

#include<iostream>
#include<string>
using namespace std;
class Person//基类
{
protected:
	string _name;//姓名
	char _sex;//性别
	int _age;//年龄
public:
	void PersonPrint()
	{
		cout << "name:" << _name << endl;
		cout << "sex:" << _sex << endl;
		cout << "age:" << _age << endl;
	}
	//Person构造函数
	Person(string name,char sex,int age) :_name(name), _sex(sex), _age(age)
	{
		cout << "Person构造" << endl;
	}
	//Person拷贝构造
	Person(const Person& p)
	{
		_name = p._name;
		_sex = p._sex;
		_age = p._age;
		cout << "Person拷贝构造" << endl;
	}
	~Person()
	{
		cout << "~Person析构" << endl;
	}
};
class Student :public Person
{
private:
	Person _teacher;//班主任(子对象)
	int _num;//学号
public:
	//Student构造函数
	Student(string name, char sex, int age, int num, const Person& teacher):Person(name, sex, age), _num(num), _teacher(teacher)
	{
		cout << "Student构造" << endl;
	}
	void StudentPrint()
	{
		PersonPrint();//打印学生的信息
		cout << "num:" << _num << endl;
		_teacher.PersonPrint();//打印老师的信息
	}
	~Student()
	{
		cout << "~Student析构" << endl;
	}
};
int main()
{
	Person teacher("zhaoli", 'F', 38);//班主任
	cout << "*******************************" << endl;
	Student s("liming", 'M', 18, 1001, teacher);//学生
	//s.StudentPrint();
	return 0;
}

c0dbabeb58454ec597c6c888bc388ff3.png

那么谁是拷贝构造的呢?

第一个构造的是Person类的班主任对象,第二个则是调用基类的构造,第三个构造的是子对象是拷贝构造

5.同名成员的处理

假如在A类(基类)和B类(派生类)中有同名数据成员m,同名函数print(),那在类外面访问他们的时候会如果我们想调用A类中的函数print()和访问A类数据成员m,可以通过创建一个A类的对象,通过对象来访问。

但是既然A类被B类通过公共继承的方式继承了,那么A类的公有数据成员m和函数print(),也被继承了,但是B类(派生类)中有同名数据成员m,同名函数print()。此时如果我们建一个B类的对象,访问数据成员m和调用函数print(),会产生二义性吗(冲突)

一起来看一下

4f8b69051908420a8dd0f250449d3442.png

证明了同名成员也被继承

3d01202794044f4db0de8503b6f8be8e.png

我们发现B类的对象访问的都是B类中的数据成员m、函数print(),A类的数据成员m、函数print()并没有被访问,也没有产生二义性,其实派生类会隐藏基类的同名成员,那我们怎么样才能通过派生类的对象,访问基类成员和成员函数呢?

其实很简单只需要加类名::即可

eef60cdeb43240a3aa4f6e57f49053ee.png

总结: 
1.子类对象可以直接访问到子类中同名成员
2.子类对象加作用域可以访问到父类同名成员
3.当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

补充

继承同名静态成员处理方式


问:继承中同名的静态成员在子类对象上如何进行访问?


静态成员和非静态成员出现同名,处理方式一致
·访问子类同名成员直接访问即可
·访问父类同名成员需要加作用域

6.多继承

6.1语法

C++允许一个类继承多个类
语法:class子类:继承方式 父类1,继承方式 父类2......
多继承可能会引发父类中有同名成员出现,需要加作用域区分

0694e9b2077c4bb39a5f2eb3791f1850.png

6.2多继承派生类的构造函数

2389e86628e247aca239d1d149b5a01d.png

注意:

⑴初始化表中基类构造函数的排列顺序任意;

⑵派生类D的构造函数的执行顺序是先调用基类的构造函数,再执行派生类构造函数的函数体;

⑶调用基类的构造函数的顺序是按照声明派生类时基类出现的顺序。

示例:

032aa8f72e29449a84869b1e7b1c72a9.png7182b9776b0b446a957b5de5a82d9aad.png

7.菱形继承

如图,先声明A类,然后由它派生出B1类、B2类,D类同时继承了B1类、B2类

当菱形继承,两个父类拥有相同数据,需要加以作用域区分

 

c0c0dcd56a1c4e959608ee01693d3b55.png

2f312277cb71472a9f1cfd226f1f48fb.png

da2652fcb68d4381bca5f6444867e01e.png

A类中的数据成员a这份数据我们知道只有有一份就可以,菱形继承导致数据有两份,造成了资源浪费,该如何解决呢?

利用虚继承可以解决,在继承方式之前 加上关键字virtual即可,此时的基类称为虚基类

f198952b5063472793091b605fc54f5e.png

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件项目建设方案编制参考模板(Word原件)

1 引言 1.1 编写目的 1.2 项目概述 1.3 名词解释 2 项目背景 3 业务分析 3.1 业务需求 3.2 业务需求分析与解决思路 3.3 数据需求分析【可选】 4 项目建设总体规划【可选】 4.1 系统定位【可选】 4.2 系统建设规划 5 建设目标 5.1 总体目标 5.2 分阶段目标【可选】 5.2.1 业务目…

迅为RK3562开发板ARM四核A53核心板瑞芯微国产人工智能Linux安卓

iTOP-3562开发板采用瑞芯微RK3562处理器&#xff0c;内部集成了四核A53Mali G52架构&#xff0c;主频2GHZ&#xff0c;内置1TOPSNPU算力&#xff0c;RK809动态调频。支持OpenGLES1.1/2.0/3.2、0penCL2.0、Vulkan 1.1内嵌高性能2D加速硬件。 内置独立NPU, 算力达 1TOPS,可用于轻…

硬件I2C读写MPU6050

硬件I2C读写MPU6050 SCL接PB10&#xff0c;SDA接PB11,但是硬件I2C引脚不可以任意指定。 查询引脚定义表&#xff0c;来规划引脚。但由于PB6,7,8,9被OLEDz占用&#xff0c;不方便接线了。 可以使用I2C2引脚&#xff0c;但必须是SCL对应PB10&#xff0c;SDA对应PB11&#xff0c;…

嵌入式Linux系统编程 — 2.3 标准I/O库:格式化I/O

目录 1 格式化I/O简介 2 格式化输出 2.1 格式化输出函数简介 2.2 格式控制字符串 format 2.3 示例程序 3 格式化输入 3.1 格式化输入简介 3.2 格式控制字符串 format 3.3 示例程序 1 格式化I/O简介 在先前示例代码中&#xff0c;经常使用库函数 printf() 来输出程序中…

数据分析中的统计学基础及Python具体实现【数据分析】

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

python的line[:-1]和line[-1]

line[:-1]其实就是去除了这行文本的最后一个字符(换行符)后剩下的部分。 line = "abcde" line[:-1] 结果为:abcd line = "abcde" line[::-1] 结果为:edcba 示例3 [m : ] 代表列表中的第m+1项到最后一项 [ : n] 代表列表中的第一项到第n项 [-1] 代…

基于jeecgboot-vue3的Flowable流程-已办任务(一)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、api接口部分 import { defHttp } from //utils/http/axios;enum Api {flowRecord /flowable/task/flowRecord,finishedListNew /flowable/task/finishedListNew,revokeProcess /flo…

2024年自然语言处理科学与信息检索技术国际会议(ICNLPSIRT 2024)

2024年自然语言处理科学与信息检索技术国际会议(ICNLPSIRT 2024) 2024 International Conference on Natural Language Processing Science and Information Retrieval Technology (ICNLPSIRT 2024) 会议地点&#xff1a;武汉&#xff0c;中国 网址&#xff1a;http://www.i…

【递归、搜索与回溯】搜索

搜索 1.计算布尔二叉树的值2.求根节点到叶节点数字之和3. 二叉树剪枝4.验证二叉搜索树5.二叉搜索树中第K小的元素6.二叉树的所有路径 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一…

深入ES6:解锁 JavaScript 类与继承的高级玩法

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; ES5、ES6介绍 文章目录 &#x1f4af;Class&#x1f35f;1 类的由来&#x1f35f;2 co…

【文献阅读】LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

目录 1. motivation2. overall3. model3.1 low rank parametrized update matrices3.2 applying lora to transformer 4. limitation5. experiment6. 代码参考文献 1. motivation 常规的adaptation需要的微调成本过大现有方法的不足&#xff1a; Adapter Layers Introduce Inf…

视创云展元宇宙虚拟展厅:开启无限可能的沉浸式体验

随着科技的飞速发展&#xff0c;元宇宙虚拟展厅已逐步成为展览行业的新宠。视创云展元宇宙虚拟展厅以其独特的魅力&#xff0c;将参观者从传统展览场所的束缚中解放出来&#xff0c;为他们呈现了一个更为广阔、更为丰富的虚拟世界。通过数字虚拟展厅这一载体&#xff0c;参观者…

如何掌握 Java 正则表达式 的基本语法及在 Java 中的应用

正则表达式是一种用于匹配字符串的模式&#xff0c;在许多编程语言中广泛使用。Java 正则表达式提供了强大的文本处理能力&#xff0c;能够对字符串进行查找、替换、分割等操作。 一、正则表达式的基本语法 正则表达式由普通字符和特殊字符组成。普通字符包括字母、数字和标点…

【Android】主界面设置-封装

在bulid文件写网址 implementation("io.github.youth5201314:banner:2.2.1") 添加主界面图片 些内容 在界面有图片&#xff0c;相同的属性封装起来 在values新建 先写风格&#xff0c;&#xff0c;再写代码 先写好这几项&#xff0c;宽高比例位置 将相同的属性…

软硬件集成项目,这个项目管理软件做的成本预算管理深得我心

最近&#xff0c;我负责了一个中大型的软硬件集成的项目&#xff0c;是对某单位的车间进行智能化改造&#xff0c;以提高生产效率&#xff0c;要确保设备运行的稳定性和安全性。项目会涉及到大量的硬件采购、安装以及多个软件的开发、集成&#xff0c;所以在实施过程中遇到了多…

【Python】实现极致:克服PyInstaller打包挑战,解决libpython3.10.so.1.0库丢失难题

【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题 大家好 我是寸铁&#x1f44a; 总结了一篇【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题✨ 喜欢的小伙伴可以…

微软必应地图的三维实景功能

偶然看到微软必应地图的三维实景功能&#xff0c;由于比较感兴趣这方面的技术&#xff0c;所以试用了一下,感觉总体来说技术上比咱们自己的技术和设计要好很多。比如这个工具栏就设计的很简洁&#xff0c;人性化&#xff1a; 而且实景地图的范围也非常大&#xff0c;建立这么大…

Windows系统中不同Java版本共存

Windows系统中不同Java版本共存的方法 在Windows系统中&#xff0c;有时我们需要同时运行多个Java应用&#xff0c;而这些应用可能依赖于不同版本的Java Development Kit (JDK) 或 Java Runtime Environment (JRE)。为了实现这种需求&#xff0c;我们需要在Windows中配置多个J…

自养号测评防关联的关键点解析, 确保店铺权重和买家账号的安全稳定

现在很多大卖都是自己管理几百个账号&#xff0c;交给服务商不是特别靠谱。你不知道服务商账号质量怎么样&#xff0c;账号一天下了多少你也不清楚&#xff0c;如果下了很多单万一封号被关联了怎么办&#xff0c;你也不知道服务商用什么卡给你下单&#xff0c;用一些低汇率和黑…

【Python Cookbook】S02E04 文本模式的匹配和查找 match()、search()、findall() 以及 捕获组和 + 的含义

目录 问题解决方案讨论 问题 本文讨论一些按照特定的文本模式进行的查找和匹配。 解决方案 如果想要匹配的只是简单文字&#xff0c;通常我们使用一些内置的基本字符串方法即可&#xff0c;如&#xff1a;str.find()&#xff0c;str.startwith()&#xff0c;str.endswith() …