抽象、多态、继承
抽象类
- 虚函数:
虚函数是在类中被声明为virtual的成员函数,虚函数的作用是实现多态性;多态性是将借口与实现进行分离;
基类的成员函数为虚函数,则派生类中的相应的函数自动变成虚函数,不一定在定义的时候需要加上virtual;
虚函数必须有定义,即使是空定义也可以;
要实现虚函数,派生类中的函数必须与基类中的函数同名,函数参数也要与基类一致;
虚函数在编译的时候不确定调用哪个函数,而是动态决定调用哪个函数;它的作用就是为了能让这个函数能在子类中能被重载,这样的话,编译器就可以使用后期绑定来实现多态了,用基类的指针调用子类的函数。
虚函数是非静态的、非内联的函数;
示例:
Virtual void print(){};
- 纯虚函数:
纯虚函数在基类中没有定义,必须在子类中加以实现;
纯虚函数的作用是为派生类提供一个一致的接口,只是个函数声明而已,告诉编译器,这个类中的纯虚函数没有定义;
Virtual void getColour() = 0;
- 抽象类:
不用来定义对象,而只作为一种基本类型用作继承的类,成为抽象类;通常作为基类,所以成为抽象基类;
凡是包含纯虚函数的类,都称为抽象类;
抽象类作为一个类族的公共接口,如果子类中没有对纯虚函数做定义,那该子类仍旧是一个抽象类,不能定义对象;
多态
多态:
程序运行时,一般先找到类,看它是否有基类,如果有基类,则找到基类中的函数,最后运行的是基类中的函数;这时,如果看到virtual关键字,就会再回到子类中找到同名函数运行;
多态的关键:一切指向基类的指针或者引用来操作对象。
多态分为:类的多态性(虚函数,又称动态多态)和函数多态性(函数重载或者运算符重载);
多态即用父类型的指针指向子类对象,通过父类指针,调用子类的成员函数,父类指针具有多态;
继承
继承分为公有继承(public)、私有继承(private)、受保护继承(protected)。
公有继承:基类的公有成员和保护成员,子类中仍旧保持原有状态,基类中的私有成员仍旧为私有成员,不能被派生类的子类访问;
私有继承:基类的公有成员和受保护的成员,在派生类中仍旧保持原有状态,不能被派生类的子类访问;
受保护继承:基类中的公有成员和保护成员,在派生类中仍旧是保护成员,并且只能被他派生类成员函数或友元访问,私有成员仍旧是私有成员。
继承是一个进程,通过继承,一个对象可以获得另一个对象的属性(包括函数),并且可以加入自己的一些特征。
从一个基类派生的继承称为单继承,派生类只有一个基类:
Class 派生类名称:访问控制关键字 基类名
{
}
从多个基类派生的继承称为多继承,派生类有多个基类;
Class 派生类名称:访问控制关键字 基类名1,访问控制关键字 基类名2
{
}
虚拟继承:为了解决多继承出现的,比如D继承B1,B2,而B1,B2又继承自A,此时,可以将B1,B2继承自A改成虚拟继承;这样能节省内存空间,但是通过继承对象访问虚基类中的成员时,必须通过某种引用完成,会增加引用寻址时间,调整this指针指向虚基类对象,这个调整是在运行时完成的。
示例源码:
#include<iostream>
#include<string>
using namespace std;
/*class A,B 虚函数实现*/
class A
{
public:
virtual void print()
{
cout<<"This is A!"<<endl;
}
};
class B:public A
{
public:
void print()
{
cout<<"This is B!"<<endl;
}
};
class animal
{
public:
virtual void getColour() = 0;
};
class Dog:public animal
{
public:
void getColour()
{
cout<<"Dog colour is yellow!"<<endl;
}
};
class Cat:public animal
{
public:
void getColour()
{
cout<<"Cat colour is write!"<<endl;
}
};
class Person
{
public:
string name;
string setName(string name)
{
this->name = name;
return this->name;
}
};
class Student:public Person
{
public:
string sex;
string setSex(string sex)
{
this->sex = sex;
return this->sex;
}
};
int main()
{
/*非多态
A a;
B b;
a.print();
b.print();
*/
/*多态
A a;
B b;
A *p1 = &a;
A *p2 = &b;
p1->print();
p2->print();
*/
/*抽象
Dog d;
Cat c;
animal *a1 = &d;
animal *a2 = &c;
a1->getColour();
a2->getColour();
*/
Student t;
string name = t.setName("aa");
string sex = t.setSex("F");
cout<<"My name is :"<< name<<endl;
cout<<"I am "<<sex<<endl;
}