c++类和类之间的关系

//类就是体现封装的思想,有权限的控制
//程序追求的最高境界是;高内聚(函数功能越单一越好,目标越专一越好),低耦合(类与其他类关系越少越好)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>

using namespace std;

class A
{
public:
private:
    int a;
};

//类与类关系1:
//类B包含有类A的成员变量,即B has A//类B依赖于类A,谁包含谁,谁就依赖于谁,因为类A的对象要先于类B创建,等类A对象创建完才能完成类B对象的创建,所以类B依赖于类A
class B
{
public:
private:
    A a;//当对象A不存在无参构造函数时,需要显示的写出初始化函数列表
};

//类与类关系2:
//类A是类C成员方法的形参,即C use A//类C依赖于类B,但耦合度类C明显低于类B
class C
{
public:
    void funcC(A a)
    {
    
    }
private:
};

//类与类关系3:
//类D继承于A,D是A的子类,A的代码都存在于类D的内部,即B is A//类D依赖于类A,继承的耦合度是极高的,但可以增加代码的重复使用
class D:public A
{
public:

private:
};

//类与类的关系3--类的继承
class Student
{
public:
    Student(int id, string name):age(10)
    {
        this->name = name;
        this->id = id;
    }
    void print()
    {
        cout << "name:" << this->name << endl;
        cout << "id=" << this->id << endl;
    }
private:
    int id;
    const int age;
    string name;
};

//c++代码的可重用性通过继承机制来实现
//父类为基类,子类为派生类
class Student1 :public Student//类Student1继承了Student,子类包含父类
{
public:
    /*
    //下面三段代码是错误的,首先Student1是Student的子类,Student1对象创建过程为先构造父类对象,在创建子类额外的变量,但父类Student要构造的话得先满足它的构造函数,即和初始化构造列表一样,指定怎么构造父类,满足父类的构造函数
    Student1()
    {
    }
    */
    //这儿也是函数初始化列表,与类里有别的类对象构造基本差不多,需要把包含的别的类的对象先构造好,再构造自己的
    //不同的是继承是在类开头继承,而类里有别的类对象则是包含在私有成员变量中,且继承创建父类的对象为匿名对象,且调用的时候继承是直接调用,类里有别的对象则需要先调用别的对象,再用别的对象调用其内部事物
    //子类先调用父类的构造函数创建一个空间(其实对象本质也就是空间),然后再调用子类本身的构造函数创建空间
    Student1(int id, string name, int score) :Student(id, name)
    {
        this->score = score;//这儿更能表明子类其实是包含父类对象的,函数初始化列表已经帮我们构造出父类对象,子类对象只要建立额外的变量并赋值,然后包含父类对象即可
    }
    void print()
    {
        Student::print();//这是表明调用的是父类里的方法,因为父类的对象为匿名对象,所以其方法的调用使用作用域形式调用
        /*
        注意子类是没有办法直接调用父类的私有成员变量的,虽然子类对象包含父类对象,但从代码上子类的私有成员变量并没有含有父类的私有成员变量,这其实又满足了私有成员变量只能在类内部访问的规则
        或者说子类对象虽然包含了父类对象,但父类对象对子类对象仍有访问权限控制,父类的私有成员变量子类是访问不到的,父类的公有成员变量子类可以访问到
        下面两段代码都是错误的
        Student::id = 1;
        this->id = 1;
        */
        cout << "score=" << this->score << endl;
    }
private:
    int score;
};

class Parent
{
//这儿的public是访问权限
public:
    int t1;//类的内部和外部都能访问
protected:
    int t2;//类的内部可以访问,类的外部不可以访问,子类也可以访问
private:
    int t3;//类的内部可以访问,类的外部不可以访问,
};

//三种继承方式,最好使用公有继承,其他两种继承基本不使用
//这儿的public是继承方式,即公有继承
//public公有继承时
//1.子类内部可以直接访问父类的public成员变量,子类的对象在类外部也可以直接访问父类的public成员变量
//2.子类内部可以直接访问父类的protected成员变量,子类的对象在类外部不可以直接访问父类的protected成员变量
//3.子类内部不可以直接访问父类的private成员变量,子类的对象在类外部也不可以直接访问父类的private成员变量
class Child1 :public Parent
{
public:
    void func()
    {
        t1 = 100;
        t2 = 200;
    }
};

//这儿的protected是继承方式,即保护继承,继承过来的对象除private变量外,其他都为protected访问权限,即子子类可以内部访问public和protected成员变量
//protected保护继承时
//1.子类内部可以直接访问父类的public成员变量,子类的对象在类外部不可以直接访问父类的public成员变量
//2.子类内部可以直接访问父类的protected成员变量,子类的对象在类外部不可以直接访问父类的protected成员变量
//3.子类内部不可以直接访问父类的private成员变量,子类的对象在类外部也不可以直接访问父类的private成员变量
class Child2 :protected Parent
{
public:
    void func()
    {
        t1 = 100;
        t2 = 200;
    }

};

//这儿的private是继承方式,即私有继承,继承过来的变量都为private访问权限,即子子类不可在类内部访问任何父类成员变量
//private私有继承时
//1.子类内部可以直接访问父类的public成员变量,子类的对象在类外部不可以直接访问父类的public成员变量
//2.子类内部可以直接访问父类的protected成员变量,子类的对象在类外部不可以直接访问父类的protected成员变量
//3.子类内部不可以直接访问父类的private成员变量,子类的对象在类外部也不可以直接访问父类的private成员变量
class Child3 :private Parent
{
public:
    void func()
    {
        t1 = 100;
        t2 = 200;
    }
};
//总结:
//继承方式本质是用来区分被继承过来的变量在子类的对象中是属于public成员变量,还是protected成员变量,还是private成员变量
//即子类的对象在类外部对继承过来的变量使用权限和这个子类又被子子类继承时这个子子类内部和外部对继承过来的变量的使用权限
//即本质上就是确定子类继承过来的对象是public,protected,private哪个访问权限
//继承方式对继承过来的变量的限制规则:对权限大的变为继承权限,权限小的保留

int main()
{
    Parent p;
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tulipless/article/details/80691593