数据抽象是面向对象编程中的一个核心概念,它允许我们将复杂的数据结构和操作封装起来,只暴露出必要的接口。通过数据抽象,我们可以隐藏实现细节,使代码更加清晰、易于维护。
类与对象
类是一种用户自定义的数据类型,它将数据和对数据的操作封装在一起。类的实例称为对象,每个对象都有自己的状态和行为。
定义类
使用 class
关键字来定义一个新的类。例如:
-- -------------------- ---- ------- ----- --- - -------- --- ------ ----------- ------ ------- ---- ------------ --------- - ----- - --------- - --- ---------- ----- - ------ ------ - ---- -------------- ------------ --------- - ----- - --------- - ----------- ---------- ----- - ------ ------ - --
在这个例子中,Car
类有两个私有成员变量 speed
和 color
,以及四个公有成员函数 setSpeed
、getSpeed
、setColor
和 getColor
。
创建对象
一旦类被定义,我们就可以创建该类的对象。例如:
Car myCar; myCar.setSpeed(60); myCar.setColor("Red");
封装
封装是数据抽象的一个重要方面,它指的是将数据和操作这些数据的方法组合成一个单独的单元,并且限制外部对这些数据的访问。封装有助于保护数据不被意外修改,并且可以确保数据的一致性和完整性。
私有和公有成员
在类中,成员变量和成员函数可以被声明为私有的或公有的。私有成员只能在类的内部访问,而公有成员可以在类的外部访问。
-- -------------------- ---- ------- ----- ----------- - -------- ------ -------- ------- ---- -------------- ------- - ------- -- ------- - ------ ------------ ----- - ------ -------- - --
在这个例子中,balance
是一个私有成员变量,只能通过 deposit
和 getBalance
方法进行访问。
访问控制
除了 private
和 public
之外,C++ 还提供了 protected
关键字,用于控制类的继承层次内的访问权限。
使用友元
有时,我们需要允许某些非成员函数或类访问类的私有成员。这时可以使用 friend
关键字。
-- -------------------- ---- ------- ----- ----------- - -------- ------ -------- ------- ---- -------------- ------- - ------- -- ------- - ------ ---- ----------------------- ------------ --------- -- ---- ----------------------- ------------ -------- - ------ --------------- - -- -
在这个例子中,isNegativeBalance
函数被声明为 BankAccount
类的友元函数,因此它可以访问 BankAccount
的私有成员 balance
。
继承
继承是面向对象编程的另一个基本特性,它允许我们创建一个新类,这个新类可以继承现有类的属性和方法。新类被称为派生类或子类,而被继承的类被称为基类或父类。
基本继承
使用 :
关键字来指定基类。例如:
-- -------------------- ---- ------- ----- --------- - ------ --- - -------- --- ----------- ------- ----------- - ------------- -- ---- -------------- ------ - ---------- - ------ - --- --------------- ----- - ------ ----------- - --
在这个例子中,SportsCar
类继承了 Car
类的所有公有成员,并添加了一个新的私有成员 turboBoost
以及相应的访问方法。
多重继承
C++ 支持多重继承,这意味着一个派生类可以从多个基类继承属性和方法。
-- -------------------- ---- ------- ----- ----------- - ------ --- - -------- ---- ----------- ------- ------------- - ----------------- -- ---- --------------- - ---------- - ----- - ---- -------------- - ---------- - ------ - ---- --------------- ----- - ------ ----------- - -- ----- --------- - ------ ---- ------ ----------- - -------- -- --------- ---- --- - ----------- -------- --
在这个例子中,HybridCar
类同时继承了 Car
和 ElectricCar
,从而拥有了两者的全部功能。
多态
多态是指同一个函数调用在不同的上下文中表现出不同的行为。C++ 中的多态主要通过虚函数来实现。
虚函数
虚函数允许我们在基类中声明一个函数,然后在派生类中重写这个函数。当通过基类指针或引用调用这个函数时,实际执行的是派生类中的版本。
-- -------------------- ---- ------- ----- ------- - ------- ------- ---- ------- - --------- -- -------- - ------- --------- -- ---------- - -- ----- --- - ------ ------- - ------- ---- ------- -------- - --------- -- -------- - ----- -- ---------- - -- ----- ---------- - ------ ------- - ------- ---- ------- -------- - --------- -- -------- - ------------ -- ---------- - -- ---- ------------------ -------- - ----------------- - --- ------ - -------- --- - --- ------ -------- ---- - --- ------------- --------------- -- --- ------- - ---- ---------------- -- --- ------- - ----------- ------ ---- ------ ----- ------ -- -
在这个例子中,Vehicle
类中的 drive
函数被声明为虚函数。Car
和 Motorcycle
类分别重写了 drive
函数。当通过 testDrive
函数调用 drive
时,实际执行的是传递对象对应的版本。
纯虚函数
纯虚函数是一种特殊的虚函数,它没有具体的实现,而是强制派生类必须提供其实现。
-- -------------------- ---- ------- ----- ------ - ------- ------- ---- ----------- ----- - -- -- ---- -- ----- --- - ------ ------ - ------- ---- ----------- ----- -------- - --------- -- ------- -- ---------- - -- ----- --- - ------ ------ - ------- ---- ----------- ----- -------- - --------- -- ------- -- ---------- - --
在这个例子中,Animal
类有一个纯虚函数 makeSound
。Dog
和 Cat
类必须实现 makeSound
函数。
总结
数据抽象是面向对象编程的基础,通过类和对象的概念,我们可以将复杂的问题分解为更简单的部分。封装、继承和多态是数据抽象的重要组成部分,它们共同构成了强大的面向对象编程范式。
接下来,我们可以继续探讨其他重要的 C++ 面向对象编程概念,如模板、异常处理等。