个人主页: :✨✨✨初阶牛✨✨✨
强烈推荐优质专栏: C++的世界(持续更新中)
推荐专栏1: C语言初阶
推荐专栏2: C语言进阶
个人信条: 知行合一
本篇简介:>:讲解C++中有关继承的概念.
金句分享:
✨那些看似不起波澜的日复一日会在某一天,让你看到坚持的意义!✨
本篇只是介绍了C++
中继承的一部分简单知识,继承的概念,继承的格式,继承方式等,
对于复杂的多继承,菱形继承,下一篇会介绍.
虽然我没有财富,但是,我爸有,他给我留下了巨大的财富,我如果不好好学习,就只能回去继承亿万家产了.
(讲个笑话,不要当真.)
那C++
中的继承是什么呢?
C++
中的继承是面向对象编程中的一个重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的公共数据和函数成员。子类可以使用父类的数据和函数,同时也可以添加自己的数据和函数,将父类的功能扩展为更具体和特定的功能,使代码更加模块化和易于维护。
在C++
中,通过在子类定义中使用关键字“public
”、“private
”和“protected
”来实现对继承的访问控制。三种方式,具体介绍在下面讲解.
C++
中的继承是面向对象编程的重要特性之一,它允许一个类继承另一个类的属性和方法。被继承的类称为基类或父类,继承的类称为派生类或子类。
派生类 +: +继承方式+基类
继承的初步体验:
#include
using namespace std;
class People//基类
{
public:
People(string name="cjn",int age=20)
:_name(name)
,_age(age)
{
cout << "People()" << endl;
}
void who(){
cout << _name << endl;
cout << _age << endl;
}
protected:
string _name;
int _age;
};
class Student:public People //派生类1 继承People类
{
public:
Student(int sno= 20216868)
:_sno(sno)
{
cout << "Student()" << endl;
}
void test(){
//可以访问基类的protect成员
_name = "王五";
_age = 66;
}
protected:
int _sno;
};
class Teacher:public People
{
public:
Teacher(string course ="Chinese")
:People("wang wu",18) //显示调用了基类的构造函数
,_course()
{
cout << "Teacher()" << endl;
}
protected:
string _course;
};
int main()
{
People p1("zhang san",25);
p1.who();
cout << endl;
Student s1(20216666);
s1.who(); //虽然Student类中并没有who方法,但是,Studen类继承了People类,在People类中定义了who方法
cout << endl;
Teacher t1("Physics");
t1.who(); //虽然Teacher类中并没有who方法,但是,Teacher类继承了People类,在People类中定义了who方法
cout << endl;
return 0;
}
运行结果:
People()
zhang san
25
People()
Student()
cjn
20
People()
Teacher()
wang wu
18
分析:
虽然两个派生类中并没有实现who
方法,但是它们都继承了People
类,所以,可以使用People
的成员和方法.
那为啥,输出的结果不一样呢?
1)因为在创建People
类时,已经传参初始化了,People p1("zhang san",25);
.
2)在创建Student
类时,并没有为People
传参赋值,所以这里编译器会采用People类的默认构造.
3)Teacher
类中,显示调用了基类的构造函数,People("wang wu",18)
继承方式有三种:
(1) “public
”(公有继承:表示父类的公共成员在子类中仍然是公共的,可以直接访问;
(2)“private
”(私有继承):表示父类的私有成员在子类中无法直接访问,只能通过父类提供的函数访问;
(3)“protected
”(保护继承):表示父类的保护成员在子类中可以直接访问。
同样,类中成员的访问限定符也有三种:
(1)public
(公有成员变量).
(2)private
(私有成员变量)
(3)protected
(保护成员变量)
继承方式与限定符 基类与派生类权限一览表
千万不要去背表格中的内容,不仅难背,还容易忘记.
总结一下很好理解的:
private
权限=min
(在基类的访问限定符,继承方式)
例外:(private无论何种继承方式都是在派生类中不可见)
这里需要注意的是,虽然在派生类中不可见,但也是被继承下来了.
如何证明也被继承下来了?
class People
{
public:
People(string name = "cjn", int age = 20, int num = 4)
:_name(name), _age(age), _num(num)
{
cout << "People()" << endl;
}
void who()
{
cout << "People_who" << endl;
cout << _name << endl << _age << endl << _num << endl;
}
public:
int _a = 3;
protected:
string _name;
int _age;
private:
int _num;
};
class Student :public People
{
public:
Student(int sno = 20216868)
:People("王五",30,90),_sno(sno)
{
cout << "Student()" << endl;
}
void who()
{
cout << "Student_who" << endl << "_sno=" << _sno << endl;
People::who();
}
protected:
int _sno;
};
int main()
{
People p1;
Student s1;
p1.who();
s1.who();
return 0;
}
试着手动分别实现一下,采用public
、protected
、private
三种继承方式,观察它们在派生类和类外面的访问权限.
还是代码演示看的清楚:
#include
using namespace std;
class People
{
public:
People(string name = "cjn", int age = 20)
:_name(name)
, _age(age)
{
cout << "People()" << endl;
}
public:
int _a = 3;
protected:
string _name;
int _age;
private:
int _num;
};
//class Student :public People //公有继承
//class Student :protected People //保护继承
class Student :private People //私有继承
{
public:
Student(int sno = 20216868)
:_sno(sno)
{
cout << "Student()" << endl;
}
void test()
{
//在派生类中可以访问基类的public成员
_a = 5;
//在派生类中可以访问基类的protect成员
_name = "王五";
_age = 66;
//不可在派生类中访问基类的私有成员,公有继承都不行,因为基类的私有成员,在派生类不可见
//_num = 20; //报错
//访问派生类自己的成员当然是可以的.
_sno = 20214321;
}
protected:
int _sno;
};
int main()
{
People* p1 = new People;
cout << endl;
Student* s1 = new Student;
s1->test();
//s1->_a = 3; //公有继承时, 派生类的指针在派生类外面也可以访问基类的public成员.
cout << endl;
return 0;
}
我们一般都使用公有继承,在公有继承下:
(1)如果我们想让成员在派生类中可以访问,在类外面不可访问,此时就适合在基类中定义为protected
成员.
(2)如果我们希望成员在派生类和类外面都可以被访问,则采用public
成员.
派生类是由继承基类后,加上自己的成员构成的,那我们只取派生类中基类的那部分,将其赋值给一个基类对象,这就类似于切割或者切片.
定义:
派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。
#include
#include
using namespace std;
class People
{
protected:
string _name;
int _age;
private:
int _num;
};
class Student :public People
{
protected:
string _course;
int _sno;
};
int main()
{
People p1; //基类对象
Student s1; //派生类对象
People* pp1 = &p1; //基类指针
Student* ps1 = &s1; //派生类指针
//子类对象可以赋值给父类对象 / 指针 / 引用
p1 = s1; //基类对象可以由子类切片赋值
pp1 = &s1; //基类指针可以指向派生类的对象中基类的那部分(切片)
People& rp1 = s1; //基类的引用也可以由派生类的初始化
//派生类对象不可由基类来赋值
//s1 = p1; //报错
//派生类指针与基类指针可以强转赋值,但是注意越界.
ps1=(Student*)pp1 ;
pp1 = (People*)ps1;
return 0;
}
C++
中的继承有以下特点:
子类可以继承父类的公有成员(public
)和保护成员(protect
),但不能直接访问父类的私有成员。
子类可以增加自己的新成员和方法。
强调一波
C++
中的继承有三种方式:
公有继承:以public
关键字继承父类,父类的公有成员和保护成员都可以在子类中访问。
保护继承:以protected
关键字继承父类,父类的公有成员和保护成员都会变成子类的保护成员。
私有继承:以private
关键字继承父类,父类的公有成员和保护成员都会变成子类的私有成员。
基类private
成员在派生类中无论以什么方式继承都是不可见的。不可见是指不能访问,不代表没有被继承下来.
基类private
成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected
。可以看出保护成员限定符是因继承才出现的。(这个上面有例子介绍)
(1) 关键字class
,也就是类默认的继承方式是private
.
(2)struct
,C++中结构体也升级为了类,但是结构体的默认的继承方式是public
,不过最好显示的写出继承方式,更容易让人理解.
在实际运用中几乎都是使用public
继承,很少有protetced/private
继承,因为继承本身就是为了得到基类的成员,公有继承更加合适.