在面向对象编程中,虚函数和纯虚函数是实现多态性的重要概念,它们在C++、Java等编程语言中有着广泛的应用,下面以C++为例详细介绍这两个概念。
虚函数
定义
虚函数是在基类中使用关键字 virtual
声明的成员函数。当一个基类指针或引用指向派生类对象时,通过该指针或引用调用虚函数,会根据实际对象的类型来决定调用哪个类的函数版本,而不是根据指针或引用的类型,这就是所谓的动态绑定或运行时多态。
语法
在基类中,虚函数的声明方式如下:
class Base {
public:
// 声明虚函数
virtual void print() {
std::cout << "This is the Base class." << std::endl;
}
};
在派生类中,可以对虚函数进行重写(override):
class Derived : public Base {
public:
// 重写基类的虚函数
void print() override {
std::cout << "This is the Derived class." << std::endl;
}
};
示例代码
#include <iostream>
class Base {
public:
virtual void print() {
std::cout << "This is the Base class." << std::endl;
}
};
class Derived : public Base {
public:
void print() override {
std::cout << "This is the Derived class." << std::endl;
}
};
int main() {
Base* basePtr;
Derived derivedObj;
basePtr = &derivedObj;
basePtr->print(); // 调用Derived类的print函数
return 0;
}
代码解释
在上述代码中,Base
类中的 print
函数被声明为虚函数。在 main
函数中,一个 Base
类型的指针 basePtr
指向了一个 Derived
类的对象 derivedObj
。当通过 basePtr
调用 print
函数时,由于 print
是虚函数,实际调用的是 Derived
类中重写的 print
函数,输出结果为 “This is the Derived class.”。
特点
-
动态绑定:虚函数实现了运行时的动态绑定,根据对象的实际类型来调用相应的函数版本,提高了程序的灵活性和可扩展性。
-
可在派生类中重写:派生类可以选择重写基类的虚函数,以实现自己的特定行为。
-
基类中必须有实现:虚函数在基类中必须有具体的实现代码。
纯虚函数
定义
纯虚函数是在基类中声明的虚函数,它没有具体的实现,而是在函数声明的末尾加上 = 0
。包含纯虚函数的类被称为抽象类,抽象类不能实例化对象,其主要作用是为派生类提供一个统一的接口规范。
语法
class Base {
public:
// 声明纯虚函数
virtual void print() = 0;
};
示例代码
#include <iostream>
class Shape {
public:
// 纯虚函数
virtual double area() = 0;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
// 实现纯虚函数
double area() override {
return 3.14 * radius * radius;
}
};
int main() {
// Shape shape; // 错误,抽象类不能实例化
Circle circle(5.0);
std::cout << "Circle area: " << circle.area() << std::endl;
return 0;
}
代码解释
在上述代码中,Shape
类是一个抽象类,其中的 area
函数是纯虚函数。Circle
类继承自 Shape
类,并实现了 area
函数。在 main
函数中,不能创建 Shape
类的对象,但可以创建 Circle
类的对象,并调用其 area
函数计算圆的面积。
特点
-
抽象类的标志:包含纯虚函数的类是抽象类,不能实例化对象。
-
派生类必须实现:派生类必须实现基类的纯虚函数,否则派生类也会成为抽象类。
-
接口规范:纯虚函数为派生类提供了一个统一的接口规范,使得不同的派生类可以有不同的实现方式。