【C++】继承/多态/文件

news2025/1/13 7:38:13

文章目录

  • 一、继承
    • 1 继承中的对象模型
    • 2 继承中构造和析构顺序
    • 3 继承中同名属性和函数处理方式(隐藏)
    • 4 继承同名静态成员属性和函数处理方式
    • 5 多继承语法
    • 6 菱形继承(虚继承)
  • 二、多态
    • 1 多态的原理剖析(虚函数表指针)
    • 2 纯虚函数和抽象类
    • 3 虚析构和纯虚析构(解决父类指针管理堆区子类析构函数)
  • 三、文件操作
    • 1 文本文件
      • 1.1 写文件(ofstream)
      • 1.2 读文件(ifstream)
    • 2 二进制文件
      • 2.1 写文件(ofstream)
      • 2.2 读文件(ifstream)

一、继承

  • 利用继承的技术,减少重复代码
  • 语法: class 子类名:继承方式 父类名

继承方式一共有三种:

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

在这里插入图片描述

1 继承中的对象模型

  • 父类中私有成员也是被子类继承下去了,只是由于编译器给隐藏后访问不到
  • 在父类中所有非静态的成员属性都会被子类继承下去
// 继承中的对象模型
class Base
{
public:
    int m_A;

protected:
    int m_B;

private:
    int m_C;
};

class Son : public Base
{
public:
    int m_D;
};
void test01()
{
    // 在父类中所有非静态的成员属性都会被子类继承下去
    // 父类中私有成员属性 是被编译器隐藏了,因此是访问不到。但是确实被继承下去了
    cout << "size of Son= " << sizeof(Son) << endl;
}
int main()
{
    test01();

    system("pause");
    return 0;
}

2 继承中构造和析构顺序

  • 创建子类对象,也会调用父类的构造函数
  • 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反。(栈的先进后出)
    在这里插入图片描述

3 继承中同名属性和函数处理方式(隐藏)

  • 访问子类同名成员,直接访问即可 s.m_A
  • 访问父类同名成员,需要加作用域 s.Base::m_A
    • 子类会隐藏掉父类中所有同名成员函数(重载的部分也隐藏
  • 若两个函数参数相同,但是基类函数不是虚函数,则会被隐藏。和重写的区别在于基类函数是否是虚函数。
  • 若两个函数参数不同,无论基类函数是不是虚函数,都会被隐藏,两个函数在同一个类中。和重载的区别在于两个函数不在同一个类中。
// 继承中同名成员处理
class Base
{
public:
    Base()
    {
        m_A = 100;
    }
    void func()
    {
        cout << "Base-func()调用" << endl;
    }
    void func(int a)
    {
        cout << "Son-func(int a)调用" << endl;
    }
    int m_A;
};

class Son : public Base
{
public:
    Son()
    {
        m_A = 200;
    }
    void func()
    {
        cout << "Son-func()调用" << endl;
    }

    int m_A;
};

// 1. 同名成员属性处理
void test01()
{
    Son s;
    cout << "Son 下 s.m_A= " << s.m_A << endl;

    // 如果通过子类对象,访问到父类中同名成员,需要加作用域
    cout << "Base 下 s.m_A=" << s.Base::m_A << endl;
}

// 2. 同名成员函数处理
void test02()
{
    Son s;
    s.func(); // 直接调用是子类中的同名成员

    s.Base::func();

    // 如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数
    // 如果想访问到父类中被隐藏的同名成员函数,需要加作用域
    // s.func(100);
    s.Base::func(100);
}
int main()
{
    test01();
    test02();

    system("pause");
    return 0;
}

4 继承同名静态成员属性和函数处理方式

静态成员变量的特点

  • 所以对象都共享同一份数据
  • 编译阶段就分配内存
  • 类内声明,类外初始化

静态成员函数的特点

  • 只能访问静态成员变量,不能访问非静态成员变量
  • 所以对象共享同一份函数实例

静态成员和非静态成员出现同名,处理方式一致:(只不过有两种访问方式:对象 和 类名

  • 访问子类同名成员 直接访问即可 s.m_A Son::m_A
  • 访问父类同名成员 需要加作用域 s.Base::m_A Son::Base::m_A
// 继承中同名静态成员处理
class Base
{
public:
    static int m_A;
    static void func()
    {
        cout << "Base-static void func()" << endl;
    }
    static void func(int a)
    {
        cout << "Base-static void func(int a)" << endl;
    }
};
int Base::m_A = 100;

class Son : public Base
{
public:
    static int m_A;
    static void func()
    {
        cout << "Son-static void func()" << endl;
    }
};
int Son::m_A = 200;

// 1. 同名静态成员属性
void test01()
{
    cout << "通过对象访问: " << endl;
    // 1、通过对象访问数据
    Son s;
    cout << "Son 下 m_A= " << s.m_A << endl;

    cout << "Base 下 m_A=" << s.Base::m_A << endl;

    // 2、通过类名访问
    cout << "通过类名访问: " << endl;
    cout << "Son 下 m_A= " << Son::m_A << endl;
    // 第一个::代表通过类名方式来访问,第二个::代表访问父类作用域下
    cout << "Base 下 m_A=" << Son::Base::m_A << endl;
}

// 2. 同名静态成员函数处理
void test02()
{
    cout << "通过对象访问: " << endl;
    // 通过对象访问
    Son s;
    s.func();
    s.Base::func();

    // 通过类名访问
    cout << "通过类名访问: " << endl;
    Son::func();
    Son::Base::func(); //

    // 当子类与父类拥有同名的成员函数,子类会隐藏掉父类中所有同名成员函数,加作用域可以访问到父类中同名函数。
    Son::Base::func(100);
}
int main()
{
    test01();
    test02();

    system("pause");
    return 0;
}

5 多继承语法

  • C++实际开发中不建议用多继承
  • 语法class 子类:继承方式 父类1,继承方式 父类2...
  • 多继承可能会引发父类中有同名成员出现,需要加作用域区分s.Base1::m_A s.Base2::m_A
// 多继承语法
class Base1
{
public:
    Base1()
    {
        m_A = 100;
    }
    int m_A;
};

class Base2
{
public:
    Base2()
    {
        m_A = 200;
    }
    int m_A;
};

// 子类 需要继承Base1和Base2
// 语法: class 子类:继承方式 父类1,继承方式 父类2...
class Son : public Base1, public Base2
{
public:
    Son()
    {
        m_C = 300;
        m_D = 400;
    }
    int m_C, m_D;
};

void test01()
{
    Son s;
    sizeof(s);
    cout << "size of Son= " << sizeof(Son) << endl; // 16
    // 当父类中出现同名的成员
    cout << "Base1::m_A= " << s.Base1::m_A << endl;
    cout << "Base2::m_A= " << s.Base2::m_A << endl;
}
int main()
{
    test01();
    // test02();

    system("pause");
    return 0;
}

6 菱形继承(虚继承)

菱形继承概念: 两个派生类继承同一个基类,又有某个类同时继承着两个派生类。

解决方式(利用虚继承):

  • 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费及毫无意义
  • 利用虚继承可以解决菱形继承问题
  • 继承方式之前加入关键字 virtual 变为虚继承 class Sheep : virtual public Animal {};
// 动物类
class Animal
{
public:
    int m_Age;
};

// Animal称为 虚基类(最大的类)
class Sheep : virtual public Animal
{
};

// 驼类
class Tuo : virtual public Animal
{
};

// 羊驼类
class SheepTuo : public Sheep, public Tuo
{
};

void test01()
{
    SheepTuo st;
    st.Sheep::m_Age = 18;
    st.Tuo::m_Age = 28;

    // 当菱形继承,两个父类拥有相同数据,需要加以作用域区分
    cout << "st.Sheep::m_Age= " << st.Sheep::m_Age << endl;
    cout << "st.Tuo::m_Age= " << st.Tuo::m_Age << endl;
    cout << "st.m_Age = " << st.m_Age << endl; // 28
                                               // 利用虚继承可以直接访问,不会有二义性
}
int main()
{
    test01();

    system("pause");
    return 0;
}
  • 没用虚函数(sheepTuo)

在这里插入图片描述

  • 用虚函数(sheepTuo)(不会出现二义性)
  • 从父类中拿到的只是一个虚基类指针而已

在这里插入图片描述

二、多态

  • C++开发提倡利用多态设计程序架构,因为多态优点很多
  • 开闭原则:对拓展进行开放,对修改进行关闭

多态分为两类

  • 静态多态:函数重载 和 运算符重载 属于静态多态,复用函数名
  • 动态多态:派生类和虚函数实现运行时多态

静态多态和动态多态区别

  • 静态多态的函数地址早绑定------编译阶段确认函数地址
  • 动态多态的函数地址晚绑定------运行阶段确认函数地址

多态满足条件

  • 有继承关系
  • 父类必须写虚函数,子类可写可不写
  • 子类重写父类中的虚函数
    • 重写:函数(返回值类型 函数名 参数列表)完全一致称为重写

多态使用条件

  • 父类指针或引用(指针必须开辟堆区)指向子类对象
class Animal
{
public:
    // 虚函数
    virtual void speak()
    {
        cout << "动物在说话" << endl;
    }
};

class Cat : public Animal
{
public:
    // 重写 函数的返回值类型 函数名和参数列表要完全相同
    void speak()
    {
        cout << "小猫在说话" << endl;
    }
};

class Dog : public Animal
{
public:
    void speak()
    {
        cout << "小狗在说话" << endl;
    }
};

// 父类的指针或引用 指向子类对象
void doSpeak(Animal &animal) // Animal &animal =cat;
{                            // 子类可以转父类,父类不能转子类
    animal.speak();
}
void test01()
{
    Cat cat;
    doSpeak(cat);

    Dog dog;
    doSpeak(dog);
}
int main()
{
    test01();

    system("pause");
    return 0;
}

1 多态的原理剖析(虚函数表指针)

  • 子类继承父类,同时也继承了虚函数表
  • 虚函数表指针指向虚函数表(记录虚函数的内容)
    • 通俗讲就是虚函数表指针指向虚函数表本身,有重写就替换

  • Animal(父类)
    在这里插入图片描述
  • Cat(子类)
    在这里插入图片描述

2 纯虚函数和抽象类

  • 通常父类中虚函数的实现是毫无意义的,主要都是调用子类中重写的内容。因此可以将虚函数改为纯虚函数
  • 纯虚函数语法: virtual 返回值类型 函数名 (参数列表)=0;
  • 当类中有了纯虚函数,这个类也成为抽象类

纯虚函数特点

  • 提供接口(父类虚函数表指针指向子类对象)
  • 不做任何实现

抽象类特点

  • 无法实例化对象
  • 子类必须重写抽象类中的纯虚函数,否则也属于抽象类
// 纯虚函数和抽象类
class Base
{
public:
    // 1、无法实例化对象
    // 2、抽象类的子类必须要重写父类中的纯虚函数,否则也属于抽象类
    virtual void func() = 0; // 纯虚函数
};

class Son : public Base
{
public:
    virtual void func()
    {
        cout << "func函数调用" << endl;
    };
};

void test01()
{
    Base *base = new Son;
    base->func();
}

int main()
{
    test01();

    system("pause");
    return 0;
}

3 虚析构和纯虚析构(解决父类指针管理堆区子类析构函数)

  • 如果子类中有属性开辟到堆区(栈区自动释放),那么父类指针在释放时无法调用到子类的析构函数
    • 父类的引用和开辟到栈区的指针可以调用子类析构和构造
  • 解决方式:将父类中的析构函数改为虚析构或纯虚析构
  • 如果子类中没有堆区数据,可以不写虚析构或纯虚析构(最好有继承关系就写虚析构!

虚析构和纯虚析构共性:(都需要函数实现

  • 可以解决父类指针释放子类对象
  • 都需要有具体的函数实现

虚析构和纯虚析构区别

  • 如果是纯虚析构,该类属于抽象类,也无法实例化对象
  • 虚析构语法:virtual ~类名(){};
  • 纯虚析构语法:virtual ~类名()=0;
  • 纯虚析构函数必须有实现

如果类包含纯虚析构函数,则必须为纯虚析构函数提供函数体

  • 原因是因为析构函数(与其它函数不同)实际上并未被 “重写”,而是始终以派生类的相反顺序调用它们。这意味着派生类的析构函数将首先被调用,然后调用基类的析构函数。
  • 如果未提供纯虚析构函数的定义,那么在销毁对象期间将调用什么函数体?
// 虚析构和纯虚析构
class Animal
{
public:
    Animal()
    {
        cout << "Animal的构造函数调用" << endl;
    }

    // 利用虚析构可以解决,父类指针释放子类对象时不干净的问题
    // virtual ~Animal()
    // {
    //     cout << "Animal的虚析构函数调用" << endl;
    // }

    // 纯虚析构 需要声明也需要实现
    // 有了纯虚析构之后,这个类也属于抽象类,无法实例化对象
    virtual ~Animal() = 0;

    // 纯虚函数
    virtual void speak() = 0;
};

// 只能在类外实现纯虚析构
Animal::~Animal() //添加这段代码就能正常运行
{
    cout << "Animal的纯虚析构函数调用" << endl;
}

class Cat : public Animal
{
public:
    Cat(string name)
    {
        cout << "Cat的构造函数调用" << endl;
        m_Name = new string(name);
    }

    ~Cat()
    {
        if (m_Name != NULL)
        {
            cout << "Cat的析构函数调用" << endl;
            delete m_Name;
            m_Name = NULL;
        }
    }

    virtual void speak()
    {
        cout << *m_Name << "小猫在说话" << endl;
    }

    string *m_Name;
};

void test01()
{
    Animal *animal = new Cat("Tom");
    animal->speak();
    // 开辟到堆区的指针,手动释放
    delete animal;
}
int main()
{
    test01();
    system("pause");
    return 0;
}

Animal的构造函数调用
Cat的构造函数调用
Tom小猫在说话
Cat的析构函数调用
Animal的纯虚析构函数调用

三、文件操作

  • 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放
  • 通过文件可以将数据持久化
  • C++中对文件操作需要包含头文件 <fstream>(文件流)

文件类型分为两种

  • 文本文件(可以看到)
    • 文件以文本的ASCII码形式存储在计算机中
  • 二进制文件
    • 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们

操作文件的三大类

  • ofstream:写操作(输出)
  • ifstream:读操作(输入)
  • fstream:读写操作(输入、输出)

1 文本文件

1.1 写文件(ofstream)

写文件步骤如下

  • 包含头文件 #include<fstream>
  • 创建流对象 ofstream ofs; (名字无所谓)
  • 打开文件 ofs.open("文件路径",打开方式);
  • 写数据 ofs<<"写入的数据";
  • 关闭文件 ofs.close();

文件打开方式

打开方式解释
ios::in为读文件而打开文件
ios::out为写文件而打开文件
ios::ate初始位置: 文件尾
ios::app追加方式写文件
ios::trunc如果文件存在先删除,再创建
ios::binary二进制方式

注意:文件打开方式可以配合使用,使用 | 操作符

  • 例如:用二进制的方式写文件ios::binary | ios::out
#include <fstream>

// 文本文件 写文件
void test01()
{
    // 1.包含头文件 fstream
    // 2.创建流对象
    ofstream ofs;

    // 3.指定打开方式
    // 没有指定路径和当前.cpp的目录一样
    // 路径可以写成绝对路径或者相对路径,或直接写文件名
    ofs.open("test1.txt", ios::out);

    // 4.写内容
    ofs << "姓名:张三" << endl;
    ofs << "性别:男" << endl;
    ofs << "年龄: 18" << endl;

    // 5.关闭文件
    ofs.close();
}

int main()
{
    test01();
    system("pause");
    return 0;
}

1.2 读文件(ifstream)

  • 读文件与写文件步骤相似,但是读取方式相对于比较多

读文件步骤如下

  • 包含头文件 #include<fstream>
  • 创建流对象 ifstream ifs;
  • 打开文件并判断文件是否打开成功 ifs.open("文件路径",打开方式);
    • 判断文件是否打开成功 ifs.is_open()
  • 读数据 四种方式读取(程序中)
  • 关闭文件 ifs.close();

文件打开方式

打开方式解释
ios::in为读文件而打开文件
ios::out为写文件而打开文件
ios::ate初始位置: 文件尾
ios::app追加方式写文件
ios::trunc如果文件存在先删除,再创建
ios::binary二进制方式
#include <fstream>
#include <string>

// 文本文件 读文件
void test01()
{
    // 1.包含头文件
    // 2.创建流对象
    ifstream ifs;

    // 3.打开文件并判断是否打开成功
    ifs.open("test.txt", ios::in);
    // 判断文件是否打开成功
    if (!ifs.is_open())
    {
        cout << "文件打开失败了" << endl;
        return;
    }

    // 4.读数据

    // 第一种
    char buf[1024] = {0};
    while (ifs >> buf) // 读到头返回一个假的标志
    {
        cout << buf << endl;
    }

    // 第二种
    char buf[1024] = {0};
    // ifs对象内有成员函数
    // ifs.getline(char *(传入首地址),sizeof()(统计字节数))

    while (ifs.getline(buf, sizeof(buf)))
    { // getline()返回bool类型
        cout << buf << endl;
    }

    // 第三种(较好)
    string buf;
    // 全局函数getline
    while (getline(ifs, buf))
    {
        cout << buf << endl;
    }

    // 第四种  不推荐
    char c;                        // EOF判断是否没有到达文件尾
    while ((c = ifs.get()) != EOF) // EOF end of file
    {                              // 中文每个占多个字节,用endl就分开了
        cout << c;
    }
    // 5.关闭文件
    ifs.close();
}
int main()
{
    test01();

    return 0;
}

2 二进制文件

文件打开方式

打开方式解释
ios::in为读文件而打开文件
ios::out为写文件而打开文件
ios::ate初始位置: 文件尾
ios::app追加方式写文件
ios::trunc如果文件存在先删除,再创建
ios::binary二进制方式
  • 以二进制的方式对文件进行读写操作
  • 打开方式要指定为 ios::binary

2.1 写文件(ofstream)

  • 二进制方式写文件主要利用输出流ofstream调用成员函数 ofs.write()
    • wirte()函数原型:ofs.write(const char* buffer, sizeof(len);
#include <fstream>

// 二进制文件 写文件
class Person
{
public:
    // 对文件操作,写字符串最好不要用C++的string,会出现问题
    char m_Name[64]; // 姓名
    int m_Age;       // 年龄
};
void test01()
{
    // 1.包含头文件
    // 2.创建流对象
    // ofs对象有构造函数,直接初始化
    ofstream ofs("person.txt", ios::out | ios::binary);

    // 3.打开文件
    // ofs.open("person.txt", ios::out | ios::binary);

    // 4.写文件
    Person p = {"张三", 18};
    // 强制转换,原来为Person*
    ofs.write((const char *)&p, sizeof(Person));

    // 5.关闭文件
    ofs.close();
}
int main()
{
    test01();

    return 0;
}

2.2 读文件(ifstream)

  • 二进制方式读文件主要利用输入流ifstream调用成员函数 ifs.read()
  • read()函数原型:ifs.read(char *buffer,sizeof(len));
#include <fstream>

class Person
{
public:
    char m_Name[64]; // 姓名
    int m_Age;       // 年龄
};

// 二进制文件读文件
void test01()
{
    // 1.包含头文件
    // 2.创建流对象
    ifstream ifs;

    // 3.打开文件 判断文件是否打开成功
    ifs.open("person.txt", ios::in | ios::binary);

    if (!ifs.is_open())
    {
        cout << "文件打开失败" << endl;
        return;
    }

    // 4.读文件
    Person p;

    ifs.read((char *)&p, sizeof(Person));

    cout << "姓名为:" << p.m_Name << endl;
    cout << "年龄为:" << p.m_Age << endl;

    // 5.关闭文件
    ifs.close();
}
int main()
{
    test01();

    return 0;
}

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

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

相关文章

【OpenSourceC#】JEngine框架

前言 一个完全依赖ILRuntime的框架&#xff0c;集成好了ILRuntime和AB资源热更&#xff0c;想用ILRuntime的可以很方便使用。 对着作者的文档JEngine看看框架功能都是怎么实现的。 看下文档中提到的功能如下 JEngine框架核心 热更资源工具 AssetMgr&#xff0c;框架集成…

询盘回复流程及外贸11步流程

询盘回复流程&#xff1a; 从事外贸的新手经常在网上寻找各种各样的外贸干货知识。其实&#xff0c;你不仅要关注某个环节的小细节&#xff0c;还要有“宏观”的思维。分过程、分步骤地梳理外贸工作&#xff0c;是外贸工作中十分重要的一个环节。今天&#xff0c;按照一般的回…

点云中点法向量,点拟合的直线,点拟合的平面

点云中点法向量 计算步骤&#xff1a; 找到点pi相邻点集合S所有点Vi,然后去中心化,并构造协方差矩阵,公式如下: 二维点云该点曲率计算方法&#xff1a; 三维点云该点曲率计算方法&#xff1a; 最小特征值对应的特征向量就是点的法向量 Eigen::Vector2d ComputeNormal(std::v…

m基于BP神经网络的房屋价值变换趋势预测matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 住宅价格是住宅市场的核心&#xff0c;住宅市场的变化关系到广大消费者的切身利益&#xff0c;商品房价格是升是降&#xff0c;销售是冷是旺&#xff0c;是社会关注的热点问题。因此&#xff0c;…

Mybatis-Plus 入门

文章目录0. 前言1. 相关概念1.1 名称介绍1.2 官网特性介绍2. 快速入门2.1 准备工作2.2.1 准备表2.2.2 创建工程2.2 入门测试2.2.1 编写实体类2.2.2 编写Mapper2.2.3 编写测试类3. CRUD3.1 条件构造器3.1.1 AbstractWrapper&#xff08;1&#xff09; 基本比较操作&#xff08;2…

想做数码管显示,单片机IO口资源不够?看看WTV890语音芯片能做些啥

在开发许多产品时许多工程师都会遇到以下问题&#xff0c;如&#xff1a;想驱动4位或10位的LED数码管显示&#xff0c;但是单片机的IO口不够用&#xff1b;要么更换IO口资源更多的MCU来控制&#xff0c;要么更换脚位丰富的单片机&#xff0c;这无疑在MCU上&#xff0c;加了1元左…

在Linux中使用at和crontab命令在指定时间计划任务服务程序

经验丰富的系统运维工程师可以使得Linux在无需人为介入的情况下&#xff0c;在指定的时间段自动启用或停止某些服务或命令&#xff0c;从而实现运维的自动化。尽管我们现在已经有了功能彪悍的脚本程序来执行一些批处理工作&#xff0c;但是&#xff0c;如果仍然需要在每天凌晨两…

2023年电气,电子与信息工程国际会议(ISEEIE 2023)

2023年电气&#xff0c;电子与信息工程国际会议&#xff08;ISEEIE 2023&#xff09; 重要信息 会议网址&#xff1a;www.iseeie.org 会议时间&#xff1a;2023年2月24-26日 召开地点&#xff1a;新加坡 截稿时间&#xff1a;2022年12月31日 录用通知&#xff1a;投稿后2周…

Mac如何做才能彻底清理垃圾

Mac磁盘空间又爆满了&#xff1f;系统运行又卡了&#xff1f;你的Mac需要清理内存缓存垃圾啦&#xff01;本文教会你如何彻底清除Mac垃圾文件&#xff0c;释放存储空间。 现在&#xff0c;Mac电脑最顶配的硬盘可达2TB。这么大的容量&#xff0c;应该够用了吧&#xff1f;可真正…

windowsserver2016安装

vmware安装windowsserver2016: 开始安装OpcServer服务器端&#xff1a; DOM配置过程&#xff1a; 1.设置OpcServer和OpcClient相同的administrator账号和密码 administrator、wong123 2.关闭OpcServer和OpcClient的防火墙 3.开启OpcServer和OpcClient远程桌面访问 4.OpcServe…

玩以太坊链上项目的必备技能(OOP-合约继承-Solidity之旅九)

继承 我们今天不讲别的&#xff0c;就只讲合约继承相关的内容。&#xff08;您是不是感觉这话挺眼熟的&#xff0c;没错&#xff0c;您确实看过&#xff0c;前一篇开头便是今天我们不讲三国&#xff0c;来讲讲 流程控制&#xff0c;您会觉得我上头了还是怎么&#xff01;&…

Java-数据库范式与表关系

数据库范式 数据库范式简介 什么是范式&#xff08;NF NormalForm&#xff09; ● 范式是符合某一种设计要求的总结 在数据库中表的设计&#xff0c;必须保证其合理性 ● 数据库表的设计关系整个系统的架构&#xff0c;关系到后续的开发效率和运行效率 如何设计合理的数据库…

【leetcode】二叉树的最近公共祖先

一、题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也…

在职位招聘数据处理中使用Loess回归曲线以及分箱、回归、聚类方法 检查离群点及光滑数据【数据挖掘机器学习】

文章目录一.需求分析二.使用局部回归&#xff08;Loess&#xff09;曲线&#xff08;增加一条光滑曲线到散布图&#xff09;方法处理数据三.使用分箱、回归、聚类方法 检查离群点及光滑数据&#xff1b;一.需求分析 本文主题&#xff1a;使用局部回归&#xff08;Loess&#x…

Jmeter(十九):nmon性能系统监控工具

一、Nmon介绍 Nmon得名于 Nigel 的监控器&#xff0c;是IBM的员工 Nigel Griffiths 为 AIX 和 Linux 系统开发的&#xff0c;使用 Nmon 可以很轻松的监控系统的CPU、内存、网络、硬盘、文件系统、NFS、高耗进程、资源和 IBM Power 系统的微分区的信息 Nmon是一款计算机性能系…

【JavaEE】HTTP + HTTPS(Part2 )

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录【HTTP响应详解】1. 认识状态码2.认识响应“报头”header3.认识响应“正文”body【通过 Java socket 构造 HTTP 请求】三、HTTPS四、Tomcat&#xff1a;http服务器THINK一个人最大的痛苦来源于对自己无能的愤怒。 【…

Pycharm SQL 警告:SQL dialect is not configured.

Pycharm SQL 警告&#xff1a;SQL dialect is not configured. 文章目录Pycharm SQL 警告&#xff1a;SQL dialect is not configured.Unable to resolve symbol XXX在我们编写python代码的时候&#xff0c;不免会在代码里面写入自己写的sql语句&#xff0c;因为很少有orm框架能…

JVM Java内存模型(JMM)

很多人将Java内存结构与Java内存模型傻傻分不清&#xff0c;Java内存模型是Java memory model&#xff08;JMM&#xff09;的意思。简单地说&#xff0c;JMM定义了一套在多线程的环境下读写共享数据&#xff08;比如成员变量、数组&#xff09;时&#xff0c;对数据的可见性、有…

浪潮开务数据库陈磊:布局数字能源,创新助力 “双碳”

​当前&#xff0c;碳中和、碳达峰无疑是国际社会最关注的热点之一。2021 年两会上&#xff0c;我国提出&#xff1a;二氧化碳排放力争于 2030 年前达到峰值&#xff0c;努力争取 2060 年前实现碳中和。“双碳” 目标的提出将推动产业转型升级&#xff0c;提高经济增长质量&…

【LeetCode题目详解】(二)206.反转链表、876.链表的中间结点

目录 一、力扣第206题&#xff1a;反转链表 1.思路一 2.思路二 二、力扣第876题&#xff1a;链表的中间结点 1.思路一 2.思路二 总结 一、力扣第206题&#xff1a;反转链表 题目链接&#xff1a;206. 反转链表 - 力扣&#xff08;Leetcode&#xff09; 题目描述&#xff1…