多态 静态多态 动态多态
抽象类提供一个框架,强制子类实现特定的功能。
多态性(Polymorphism)是面向对象编程的一个核心概念,它允许相同的操作作用于不同的对象上,并且可以根据对象的实际类型执行不同的操作。多态性有两种主要形式:静态多态性和动态多态性。
一、多态性
多态性(Polymorphism)指的是相同的接口可以对应不同的实现,使同一操作能够作用于不同的对象并表现出不同的行为。
二、静态多态性
静态多态性(Static Polymorphism),也称为编译时多态性,是在编译时决定调用哪个方法。常见的实现方式包括方法重载和运算符重载。
1. 方法重载
方法重载(Function Overloading)是指在同一个类中,多个函数的名字相同,但参数列表不同(参数的数量或类型不同)。编译器根据函数调用时传递的参数来决定调用哪个具体函数。
#include <iostream>
class MathOperations {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
int main() {
MathOperations math;
std::cout << math.add(5, 3) << std::endl; // 调用第一个 add 方法
std::cout << math.add(2.5, 3.5) << std::endl; // 调用第二个 add 方法
std::cout << math.add(1, 2, 3) << std::endl; // 调用第三个 add 方法
return 0;
}
2. 运算符重载
运算符重载(Operator Overloading)是指允许开发者定义或改变运算符的行为。在C++中,可以重载大多数运算符。
#include <iostream>
class Complex {
public:
double real, imag;
Complex(double r, double i) : real(r), imag(i) {}
Complex operator+(const Complex& other) {
return Complex(real + other.real, imag + other.imag);
}
void display() {
std::cout << real << " + " << imag << "i" << std::endl;
}
};
int main() {
Complex c1(1.0, 2.0), c2(2.0, 3.0);
Complex c3 = c1 + c2;
c3.display(); // 输出 "3.0 + 5.0i"
return 0;
}
三、动态多态性
动态多态性(Dynamic Polymorphism),也称为运行时多态性,是在运行时决定调用哪个方法。常见的实现方式包括虚函数和纯虚函数。
1. 虚函数
虚函数(Virtual Functions)允许子类重写父类的方法。在运行时,调用的具体方法取决于对象的实际类型。
#include <iostream>
class Animal {
public:
virtual void makeSound() {
std::cout << "Animal makes a sound" << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
std::cout << "Dog barks" << std::endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
std::cout << "Cat meows" << std::endl;
}
};
int main() {
Animal* myDog = new Dog();
Animal* myCat = new Cat();
myDog->makeSound(); // 输出 "Dog barks"
myCat->makeSound(); // 输出 "Cat meows"
delete myDog;
delete myCat;
return 0;
}
2. 纯虚函数
接口实现(通过抽象类)
C++没有直接的接口,但可以通过纯虚函数(pure virtual function)和抽象类来实现接口的效果。
#include <iostream>
class Drawable {
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Drawable {
public:
void draw() override {
std::cout << "Drawing Circle" << std::endl;
}
};
class Rectangle : public Drawable {
public:
void draw() override {
std::cout << "Drawing Rectangle" << std::endl;
}
};
int main() {
Drawable* shapes[] = {new Circle(), new Rectangle()};
for (Drawable* shape : shapes) {
shape->draw(); // 根据实际对象类型调用相应的 draw 方法
}
// 释放内存
for (Drawable* shape : shapes) {
delete shape;
}
return 0;
}
四、静态多态性 vs 动态多态性
总结
多态性是面向对象编程的重要特性,通过静态多态性和动态多态性实现对象的多样性和灵活性。静态多态性在编译时决定方法的选择,主要通过方法重载和运算符重载实现,而动态多态性在运行时决定方法的选择,主要通过虚函数和抽象类实现。理解并灵活运用这两种多态性,对于编写高效、可维护和可扩展的代码至关重要。
抽象类
抽象类是面向对象编程中的一个概念,它是一种不能被实例化的类,专门用来定义子类的通用接口和行为。抽象类包含至少一个纯虚函数(pure virtual function),也可以包含其他普通成员函数和数据成员。抽象类的主要目的是为子类提供一个通用的框架,强制子类实现某些特定的函数,从而实现多态性。
抽象类的特点
不能实例化:抽象类不能创建对象,只能被继承。
包含纯虚函数:纯虚函数是没有具体实现的函数,必须在派生类中实现。
可以包含普通成员:抽象类可以包含数据成员和已经实现的普通成员函数。
用于定义接口:抽象类提供一个框架,强制子类实现特定的功能。
纯虚函数
纯虚函数是一个在基类中声明但没有定义的函数。它的声明形式如下:
virtual void functionName() = 0;
//= 0表示该函数是纯虚函数,必须在派生类中实现。
以下是一个包含纯虚函数的抽象类的示例:
#include <iostream>
// 抽象类
class Animal {
public:
// 纯虚函数
virtual void makeSound() = 0;
// 普通成员函数
void sleep() {
std::cout << "Animal is sleeping" << std::endl;
}
};
// 派生类
class Dog : public Animal {
public:
void makeSound() override {
std::cout << "Dog barks" << std::endl;
}
};
// 派生类
class Cat : public Animal {
public:
void makeSound() override {
std::cout << "Cat meows" << std::endl;
}
};
int main() {
// Animal a; // 错误!不能实例化抽象类
Dog myDog;
Cat myCat;
myDog.makeSound(); // 输出 "Dog barks"
myDog.sleep(); // 输出 "Animal is sleeping"
myCat.makeSound(); // 输出 "Cat meows"
myCat.sleep(); // 输出 "Animal is sleeping"
// 使用基类指针实现多态
Animal* animals[] = {&myDog, &myCat};
for (Animal* animal : animals) {
animal->makeSound(); // 输出 "Dog barks" 和 "Cat meows"
}
return 0;
}
解释
抽象类 Animal:
包含一个纯虚函数 makeSound,表示所有派生类都必须实现这个函数。
包含一个普通成员函数 sleep,可以在派生类中直接使用。
派生类 Dog 和 Cat:
都继承了 Animal 并实现了纯虚函数 makeSound。
多态性:
在 main 函数中,使用基类指针数组 animals 指向不同的派生类对象,并调用它们的 makeSound 方法。程序会根据实际对象类型调用相应的实现。
总结
抽象类是定义一组通用接口和行为的类,包含至少一个纯虚函数,不能被实例化。它们为派生类提供了一个框架,强制派生类实现特定的功能,从而实现多态性。通过使用抽象类,可以编写更加灵活和可扩展的代码。
更多推荐
所有评论(0)