8、面向对象-继承

一、继承的概念

继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程。例如类 B 继承于类 A,那么 B 就拥有 A 的成员变量和成员函数。被继承的类称为父类或基类,继承的类称为子类或派生类

二、继承权限和继承方式

1、语法

在子类后添加     :加权限+类名

派生类属于基类的外部,不能直接访问private的变量。

需要将private修改为protected:保护权限,用于衍生类的继承

#include <iostream>
#include <cstring>

using namespace std;

class Person       //父类或者基类
{
//private:
protected:            //保护权限:类的内部可以访问,类的派生类可以访问。类的外部不能访问。
	char name[32];
	int age;
public:
	Person()
	{
		strcpy(name,"aaa");
		age = 20;
	}
};

class Student : public Person       //子类或者派生类 public 继承的权限
{
private:
	int id;
public:
	Student(int id)
	{
		this->id = id;
	}
	void show()
	{
		cout << name << " " << age << " " << id <<endl; 
		//cout << id << endl;
	}
};

int main()
{
	Student s1(1);
	s1.show();

	return 0;
}

2、继承的权限

1、继承的变量会根据继承的权限,来变更变量的权限,限制了成员在派生类中的最高权限
(例如原来是公有权限,继承权限是私有,那么在子类会变成私有变量,权限的保护程度只能提高,不能降低,例如保护变量,不会降低成为公有变量)

2、私有变量可以继承,但是不能被继承访问,因为私有变量是类私有的,是不能被外部类访问继承的

#include <iostream>

using namespace std;

class TestA
{
private:           //私有变量不能被继承访问
	int a;         //只能在类的内部访问
protected:
	int b;
public:
	int c;
};

//私有继承
class TestB : private TestA
{
//原本b是protected权限,继承以后降级为private     共有和保护都变成了私有
//相当于:private:int b
public:
	void test()
	{
		//a++;      //在testA中 A是私有成员变量,不能访问
		b++;
		c++;
	}
};

//保护继承
class TestC : protected TestA
{
//c原来是共有继承,被保护权限后,共有变量变成保护变量
public:
	void test()
	{
		//a++;
		b++;
		c++;
	}
};

class TestD : public TestA
{

public:
	void test()
	{
		//a++
		b++;
		c++;
	}
};

//限制了成员在派生类中的最高权限
int main()
{
	TestB tb;
	//tb.b;           不能访问了
	//tb.c;
	TestD td;
	//td.b;        b继承下来还是保护权限,不能在外部访问。
	td.c;

	return 0;
}

三、继承中的构造和析构

1、继承中的对象模型

①继承的变量占多少字节在子类就占多少字节

②子类继承下来的基类变量放在前面,再存放子类成员

#include <iostream>

using namespace std;

class Person
{
public:
	int age;
};

class Student :public Person       //继承下来的放在前面
{
public:
	int id;
};

int main()
{
	Student s;
	cout << sizeof(s) << endl;
	
	cout << &s << endl;
	cout << &s.age << endl;
	cout << &s.id << endl;

	return 0;
}

2、继承中的构造析构调用原则 

1、创建派生类对象,会调用基类构造函数

2、当基类没有提供无参构造函数时,派生类需要通过对象初始化链表类传参

3、析构的顺序和构造相反,先入后出

4、构造顺序:先构造父类,再构造成员,最后构造自己。

#include <iostream>
#include <cstring>

using namespace std;

class Person       //父类或者基类
{
//private:
protected:            //保护权限:类的内部可以访问,类的派生类可以访问。类的外部不能访问。
	char name[32];
	int age;
public:
	/*Person()
	{
		cout << "person的构造函数" << endl;
		strcpy(name,"aaa");
		age = 20;
	}*/

	Person(const char *n,int a)
	{
		cout << "Person有参构造函数" << endl;
		strcpy(name,n);
			age = a;
	}
	~Person()
	{
		cout << "Person 析构函数"<< endl;
	}
};

class Date
{
protected :
	int year;
	int mouth;
	int day;
public :
	Date(int y,int m,int d)
	{
		cout << "Date有参构造函数" << endl;
		year = y;
		mouth = m;
		day = d;
	}
	~Date()
	{
		cout << "Date析构函数" << endl;
	}
};

class Student : public Person       //子类或者派生类 public 继承的权限
{
//先构造父类,再构造成员,最后构造自己。
private:
	Date birth;
	int id;
public:
	Student(int id) : Person("aaa",23),birth(1,1,1)      //当基类没有提供无参构造函数时,派生类需要通过对象初始化链表类传参
	{
		cout << "Student构造函数" << endl;
		this->id = id;
	}
	void show()
	{
		cout << name << " " << age << " " << id <<endl; 
		//cout << id << endl;
	}

	~Student()
	{
		cout << "Student 析构函数" << endl;
	}
};

int main()
{
	Student s1(1);     //创建派生类对象,会调用基类构造函数,来初始化继承来的成员
	s1.show();

	return 0;        //析构的顺序和构造相反,先入后出
}

3、继承中的同名成员变量处理方法

1、同名,不会被覆盖

2、如果是同名,默认调用派生类函数(在派生类被隐藏)

3、调用基类函数,可以添加作用域。

#include <iostream>

using namespace std;

class TestA
{
private:
	int a;
public:
	void show()
	{
		cout << "this is TestA" << endl;
	}
};

class TestB : public TestA
{
private:
	int a;
public:
	void show()
	{
		cout << "this is TestB" << endl;
	}	
};

int main()
{
	TestB tb;
	cout << sizeof(TestB) << endl;           //没有被覆盖
	tb.show();         //如果是同名,默认调用派生类函数
	tb.TestA::show();

	return 0;
}

4、派生类中的static关键字

派生类,基类共享同一个静态成员变量

#include <iostream>

using namespace std;

class Person
{
public:
	static int count;

	Person()
	{
		count++;
	}
};

int Person::count = 0;

class Student : public Person
{
	
};

int main()
{
	Student s1;
	Student s2;
	Student s3;
	Person p1;
	Person p2;

	cout << Person::count << endl;         //派生类,基类共享同一个静态成员变量
	cout << Student::count << endl;
	cout << s1.count << endl;

	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值