我们想要实现多态,于是有了虚方法的概念,方便我们通过基类的指针去调用子类的同名方法。但这样还不够,有的时候并不能在基类中去定义一个适用于所有子类的方法,或者我们希望该方法对于不同的子类有截然不同的实现,而在基类中我们只需要一个空实现就可以了,于是此时就引入了抽象方法的概念。
抽象方法
抽象方法就是只有声明而没有实现的方法,一般抽象方法都是基类中的方法,并且与虚方法同时存在,语法如下:
virtual void test() = 0;
在函数声明的末尾加上“ = 0” 就表示这是一个抽象方法,告诉编译器不要在这个类中去找它的实现。 而具体的实现在子类中的覆盖方法内。
注意:子类中必须是基类中抽象方法的覆盖,即与抽象方法同名且同参数,不可以是重载。因为我们用基类指针其实只能调用基类的方法,只不过通过定义虚方法使得编译器在运行时去调用了子类的覆盖方法,但对于子类中存在的与基类不同的方法,是无法通过基类指针调用的,所以在子类中重载基类的抽象方法是无法被基类指针调用到的。
实现例子
#include <iostream>
using namespace std;
class BaseClass
{
public:
virtual void test() = 0;
};
class SubAClass : public BaseClass
{
public:
void test();
};
class SubBClass : public BaseClass
{
public:
void test();
};
void SubAClass::test()
{
cout << "This is A test!" << endl;
}
void SubBClass::test()
{
cout << "This is B test!" << endl;
}
int main()
{
BaseClass *a = new SubAClass;
BaseClass *b = new SubBClass;
a->test();
b->test();
delete a;
delete b;
return 0;
}
我们在基类BaseClass中声明了一个名为test的抽象方法,有两个子类SubAClass和SubBClass,它们定义了不同实现的test的覆盖方法。然后我们通过两个基类的指针a和b去访问它们的test方法,打印如下:
This is A test!
This is B test!
可以看到,我们用基类指针可以访问不同子类中的test方法。