多重继承如何成?
摘要:多重继承基本概念 定义 多重继承是C++独有的面向对象特性(Java、C#等语言不原生支持),指一个类同时继承自多个父类,子类会拥有所有父类的属性和方法,对应现实中“一个事物具有多个身份”的场景。 语法格
多重继承基本概念
定义
多重继承是C++独有的面向对象特性(Java、C#等语言不原生支持),指一个类同时继承自多个父类,子类会拥有所有父类的属性和方法,对应现实中“一个事物具有多个身份”的场景。
语法格式:
class 子类名 : 继承方式 父类1, 继承方式 父类2, ..., 继承方式 父类n {
// 子类成员
};
示例:水陆两栖装甲车(既是车也是船)
// 父类1:车
class Car {
int x;
public:
Car(int x=0):x(x){}
void show(){cout << x << endl;}
};
// 父类2:船
class Boat {
float y;
public:
Boat(float y=0.0):y(y){}
void show(){cout << y << endl;}
};
// 子类:水陆两栖装甲车(多重继承Car和Boat)
class AmphibiousVehicle : public Car, public Boat {
public:
AmphibiousVehicle(int x=0, float y=0.0);
};
构造函数
多重继承的子类构造时,需在初始化列表中显式调用每个父类的构造函数(若未显式调用,则默认调用父类的无参构造函数)。
实现示例:
// 子类构造函数实现
AmphibiousVehicle::AmphibiousVehicle(int x, float y)
: Car(x), Boat(y) // 按继承顺序调用父类构造
{
// 子类自身初始化逻辑
}
二义性问题
当多个父类拥有重名的方法或属性时,子类直接调用该成员会产生“二义性”(编译器无法确定调用哪个父类的版本),导致编译错误。
错误示例:
int main() {
AmphibiousVehicle v(100, 1.23);
v.show(); // 错误:Car和Boat都有show(),二义性
}
重名成员处理
解决二义性的核心是使用 域解析符:: 明确指定父类来源。
正确调用示例:
int main() {
AmphibiousVehicle v(100, 1.23);
v.Car::show(); // 调用Car类的show(),输出100
v.Boat::show(); // 调用Boat类的show(),输出1.23
// 若有重名属性,同样用域解析符
// 假设Car和Boat都有name属性
// v.Car::name = "越野车";
// v.Boat::name = "快艇";
}
拓展:多重继承的优缺点
优点
直观表达“多身份”场景(如两栖车=车+船)
代码复用更灵活,可整合多个父类的功能
缺点
二义性问题:重名成员需手动处理
逻辑复杂度高:类关系混乱,可读性下降
菱形继承陷阱:多个父类继承自同一基类时产生数据冗余
兼容性差:其他OOP语言(Java、C#)不支持,跨语言移植困难
菱形继承(钻石继承)
定义与问题
当多重继承的多个父类共同继承自同一个基类时,子类会包含该基类的多个副本(数据冗余),类关系呈菱形结构,称为菱形继承。
