在C++中,类与类之间的关系有组合与继承两种,以生活中的例子来举例,组合就好比电脑这个类由主板、CPU、内存、硬盘等这些类组成的,属于整体与部分的关系,如下图:
而继承则好比电脑与苹果电脑、戴尔电脑之间的关系,也叫父子关系,电脑为父类,苹果电脑与戴尔电脑为子类,如下:
先来讨论类的组合关系:
- 将其他类的对象作为当前类的成员使用
- 成员对象与当前类的对象生命周期相同
- 成员对象在用法上与普通对象完全一致
下边来看一段代码:
#include <iostream>
#include <string>
using namespace std;
class CPU
{
public:
void fun()
{
cout << "I'm CPU" << endl;
}
};
class Disk
{
public:
void fun()
{
cout << "I'm Disk" << endl;
}
};
class Computer
{
public:
CPU m_cpu; //以CPU类的一个对象作为Computer类的成员变量
Disk m_disk; //以Disk类的一个对象作为Computer类的成员变量
void fun()
{
cout << "I'm Computer" << endl;
}
};
int main()
{
Computer computer;
computer.fun();
computer.m_cpu.fun(); //调用CPU对象成员的fun()
computer.m_disk.fun(); //调用Disk对象成员的fun()
system("pause");
}
编译输出如下:
可以看到,使用成员对象与使用普通对象的方法是一致的,仅仅是多了嵌套而已,也可以在成员对象所在的类中再加入成员对象,好比CPU这个类中又有电阻电容这些类对象一样,可以层层嵌套。
类的组合关系比较简单,下边来看看类的继承关系
- 被继承的类叫父类(或基类),继承后的类叫子类(或派生类),如电脑类便是父类,苹果电脑、戴尔电脑等便是子类
- 子类拥有父类的所有属性和行为
- 子类就是一种特殊的父类
- 子类对象可以当作父类对象使用
- 子类中可以添加父类没有的方法和属性(好比苹果电脑可以增加自己特有的功能)
在C++中,要继承一个父类,我们可以使用public(公有继承)protect(保护继承)与private(私有继承),三种继承方式,使得子类对父类拥有不同的权限,但是当今的项目开发及C++升级的语言(java、C#)只保留的public继承,即公有继承,所以我们在这里只讨论public继承,具体语法如下
下边我们就以代码来把电脑跟苹果电脑实例化一下
#include <iostream>
#include <string>
using namespace std;
class Computer
{
private:
int m_value;
public:
void ComputerFun()
{
cout << "I'm Computer" << endl;
}
};
class AppleComputer : public Computer //继承与Computer类,拥有Computer类中的所有属性
{
private:
int m_appleValue;
public:
void AppleComputerFun()
{
cout << "I'm AppleComputer" << endl;
}
};
int main()
{
AppleComputer apple;
apple.ComputerFun(); //调用的是父类的成员函数
apple.AppleComputerFun(); //调用的是子类新增的成员函数
system("pause");
}
编译输出:
在代码中我们将AppleComputer类继承与Computer类,然后main函数中定义一个AppleComputer类对象,此时子类AppleComputer就拥有了父类Computer的所有属性,包括成员变量和成员函数,所以我们就能通过子类对象直接调用父类的公有成员函数,其实这时候的AppleComputer类本质如下:
class AppleComputer : public Computer //继承与Computer类,拥有Computer类中的所有属性
{
private:
int m_value; //继承自父类的成员变量
int m_appleValue; //子类自身的成员变量
public:
void AppleComputerFun() //子类自身的成员函数
{
cout << "I'm AppleComputer" << endl;
}
void ComputerFun() //继承自父类的成员函数
{
cout << "I'm Computer" << endl;
}
};
这时候我们就明白了为何子类对象能直接调用父类中的公有成员函数。
- 子类就是一个特殊的父类
- 子类对象可以直接初始化父类对象,反之不行
- 子类对象可以直接赋值给父类对象,反之不行
从内存的角度考虑,子类对象初始化或赋值给父类对象,初始化或赋值的内容只是继承自父类的那部分内容
下半边代码来验证一下:
#include <iostream>
#include <string>
using namespace std;
class Computer
{
private:
int m_value;
public:
void setPValue(int i)
{
m_value = i;
}
int getPValue()
{
return m_value;
}
};
class AppleComputer : public Computer //继承与Computer类,拥有Computer类中的所有属性
{
private:
int m_appleValue;
public:
void setCValue(int i)
{
m_appleValue = i;
}
int getCValue()
{
return m_appleValue;
}
};
int main()
{
AppleComputer apple;
apple.setPValue(10); //设置继承自父类的成员变量为10
apple.setCValue(20);
Computer com = apple; //把子类直接初始化父类,这时候便是将子类中集成自父类的那部分初始给父类对象com
//也就是com中的成员变量被初始化为10
cout << "apple.getPValue() = " << apple.getPValue() << endl; //10
cout << "apple.getCValue() = " << apple.getCValue() << endl; //20
cout << "com.getPValue() = " << com.getPValue() << endl; //10
system("pause");
}
编译输出:
继承是C++中代码复用的重要手段。通过继承,可以获得父类的所有功能,并且可以在子类中重写已有的功能,或者添加新功能。
总结:
- 继承是面向对象中类之间的一种关系
- 子类拥有父类的所有属性和行为
- 子类对象可以作为父类对象使用
- 子类中可以添加父类没有的方法和属性
- 继承是面向对象中代码复用的重要手段