目录
1.纯虚函数与抽象类
有时候并不是所有的函数都能在基类中实现,因为无法确定具体实现。这样的一个类成为抽象类。
例如:将Shape定义为基类,我们无法确定Shape类中的draw()方法的具体实现,但是可以确定每个子类必须实现draw()。
类似地,一个Animal类无法确定move()方法的实现,但是所有的具体animal是知道move()的实现的。
抽象类不能创建具体对象。
C++中的纯虚函数(或抽象函数)就是一个无法实现的虚函数,只是声明它。纯虚函数在声明时赋值为0。
参考下面例子:
// 抽象类
class Test
{
public:
// 纯虚函数
virtual void show() = 0;
};
下面是一个完整例子:纯虚函数在抽象类的继承类中实现。
#include<iostream>
using namespace std;
class Base
{
int x;
public:
virtual void fun() = 0;
int getX() { return x; }
};
//此类继承自Base类,并实现了fun方法
class Derived: public Base
{
int y;
public:
void fun() { cout << "fun() called"; }
};
int main(void)
{
Derived d;
d.fun();
return 0;
}
运行结果:
fun() called
2.纯虚函数的特性
2.1纯虚函数与抽象类
至少拥有一个纯虚函数才是抽象类。
下面例子中,Test是一个抽象类,因为它包含了一个纯虚函数show()。
#include<iostream>
using namespace std;
class Test
{
int x;
public:
virtual void show() = 0;
int getX() { return x; }
};
int main(void)
{
Test t;
return 0;
}
编译失败,因为Test是一个抽象类。
Compiler Error: cannot declare variable 't' to be of abstract type 'Test' because the following virtual functions are pure within 'Test': note:
virtual void Test::show()
2.2使用抽象类的指针或引用
虽然抽象类不能直接创建具体对象,但可以使用它的指针或者引用。
下面程序工作正常。
#include<iostream>
using namespace std;
class Base
{
public:
virtual void show() = 0;
};
class Derived: public Base
{
public:
void show() { cout << "In Derived \n"; }
};
int main(void)
{
Base *bp = new Derived();
bp->show();
return 0;
}
运行结果:
In Derived
2.3子类中的纯虚函数
如果子类中不覆写这个纯虚函数,则子类也会变为抽象类。
参考下面程序。
#include<iostream>
using namespace std;
class Base
{
public:
virtual void show() = 0;
};
class Derived : public Base { };
int main(void)
{
Derived d;
return 0;
}
编译错误:
Compiler Error: cannot declare variable 'd' to be of abstract type 'Derived' because the following virtual functions are pure within 'Derived': virtual void Base::show()4)
3.抽象类可以有构造函数
下面程序工作正常
#include<iostream>
using namespace std;
//带有构造函数的抽象类
class Base {
protected:
int x;
public:
virtual void fun() = 0;
Base(int i) { x = i; }
};
class Derived : public Base {
int y;
public:
Derived(int i, int j) :Base(i) { y = j; }
void fun() { cout << "x = " << x << ", y = " << y; }
};
int main(void) {
Derived d(4, 5);
d.fun();
return 0;
}
运行结果:
x = 4, y = 5
4.与Java比较
在Java中,可以使用关键字abstract声明一个抽象类。同样,可以使用abstract将一个函数声明为纯虚函数或抽象函数。
接口与抽象类:
一个接口不会实现它的任何方法,可以将其视作方法声明的收集。在C++中,接口类中会将其所有方法定义为纯虚。在Java中,有一个单独的关键字interface.