目录
C++ OOP
C++ What is OOP?
OOP 代表面向对象编程。
过程式编程是编写对数据执行操作的过程或函数,而面向对象编程是创建包含数据和函数的对象。
与过程式编程相比,面向对象编程有几个优点:
- OOP 更快、更容易执行
- OOP 为程序提供了清晰的结构
- OOP 有助于保持 C++ 代码干燥“不要重复自己”,并使代码更易于维护、修改和调试
- OOP 使得用更少的代码和更短的开发时间创建完全可重用的应用程序成为可能
提示:“不要重复自己”(DRY) 原则是关于减少代码的重复。您应该提取应用程序中常见的代码,并将它们放在一个位置并重用它们,而不是重复它们。
C++ What are Classes and Objects?
类和对象是面向对象编程的两个主要方面。
请看下图以了解类和对象之间的区别:
Another example:
因此,类是对象的模板,对象是类的实例。
创建各个对象时,它们会继承该类的所有变量和函数。
您将在下一章中了解有关类和对象的更多信息。
C++ Classes and Objects
C++ 是一种面向对象的编程语言。
C++ 中的所有内容都与类和对象及其属性和方法相关联。例如:在现实生活中,汽车是一个物体。汽车具有重量和颜色等属性,以及驱动和制动等方法。
属性和方法基本上是属于类的变量和函数。这些通常被称为“班级成员”。
类是我们可以在程序中使用的用户定义的数据类型,它充当对象构造函数或创建对象的“蓝图”。
Create a Class
要创建类,请使用 class 关键字:
- Example
Create a class called “MyClass”:
class MyClass { // The class
public: // Access specifier
int myNum; // Attribute (int variable)
string myString; // Attribute (string variable)
};
- 示例解释
class 关键字用于创建一个名为 MyClass 的类。
public 关键字是一个访问说明符,它指定可以从类外部访问该类的成员(属性和方法)。稍后您将了解有关访问说明符的更多信息。
类内部有一个整型变量 myNum 和一个字符串变量 myString。当变量在类中声明时,它们称为属性。
最后,类定义以分号;结束。
Create an Object
在 C++
中,对象是从类创建的。我们已经创建了名为 MyClass
的类,所以现在我们可以使用它来创建对象。
要创建 MyClass
对象,请指定类名,后跟对象名。
要访问类属性(myNum
和 myString
),请在对象上使用点语法 (.)
:
- Example
Create an object called “myObj” and access the attributes:
class MyClass { // The class
public: // Access specifier
int myNum; // Attribute (int variable)
string myString; // Attribute (string variable)
};
int main() {
MyClass myObj; // Create an object of MyClass
// Access attributes and set values
myObj.myNum = 15;
myObj.myString = "Some text";
// Print attribute values
cout << myObj.myNum << "\n";
cout << myObj.myString;
return 0;
}
Multiple Objects
You can create multiple objects of one class:
- example
// Create a Car class with some attributes
class Car {
public:
string brand;
string model;
int year;
};
int main() {
// Create an object of Car
Car carObj1;
carObj1.brand = "BMW";
carObj1.model = "X5";
carObj1.year = 1999;
// Create another object of Car
Car carObj2;
carObj2.brand = "Ford";
carObj2.model = "Mustang";
carObj2.year = 1969;
// Print attribute values
cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n";
return 0;
}
C++ Class Methods
Class Methods
方法是属于该类的函数。
有两种方法可以定义属于类的函数:
- 内部类定义
- 外部类定义
在下面的示例中,我们在类中定义一个函数,并将其命名为“myMethod”。
注意:访问方法就像访问属性一样;通过创建该类的对象并使用点语法 (.): - Inside Example
class MyClass { // The class
public: // Access specifier
void myMethod() { // Method/function defined inside the class
cout << "Hello World!";
}
};
int main() {
MyClass myObj; // Create an object of MyClass
myObj.myMethod(); // Call the method
return 0;
}
要在类定义之外定义函数,必须在类内部声明它,然后在类外部定义它。这是通过指定类的名称、作用域解析 :: 运算符和函数名称来完成的:
- Outside Example
class MyClass { // The class
public: // Access specifier
void myMethod(); // Method/function declaration
};
// Method/function definition outside the class
void MyClass::myMethod() {
cout << "Hello World!";
}
int main() {
MyClass myObj; // Create an object of MyClass
myObj.myMethod(); // Call the method
return 0;
}
Parameters
You can also add parameters:
- Example
#include <iostream>
using namespace std;
class Car {
public:
int speed(int maxSpeed);
};
int Car::speed(int maxSpeed) {
return maxSpeed;
}
int main() {
Car myObj; // Create an object of Car
cout << myObj.speed(200); // Call the method with an argument
return 0;
}
C++ Constructors
Constructors
C++中的构造函数是一种特殊的方法,在创建类的对象时会自动调用它。
要创建构造函数,请使用与类相同的名称,后跟括号 ():
- Example
class MyClass { // The class
public: // Access specifier
MyClass() { // Constructor
cout << "Hello World!";
}
};
int main() {
MyClass myObj; // Create an object of MyClass (this will call the constructor)
return 0;
}
Constructor Parameters
构造函数还可以接受参数(就像常规函数一样),这对于设置属性的初始值非常有用。
以下类具有品牌、型号和年份属性,以及具有不同参数的构造函数。在构造函数内部,我们将属性设置为等于构造函数参数(brand=x 等)。当我们调用构造函数(通过创建类的对象)时,我们将参数传递给构造函数,构造函数会将相应属性的值设置为相同:
- Example
class Car { // The class
public: // Access specifier
string brand; // Attribute
string model; // Attribute
int year; // Attribute
Car(string x, string y, int z) { // Constructor with parameters
brand = x;
model = y;
year = z;
}
};
int main() {
// Create Car objects and call the constructor with different values
Car carObj1("BMW", "X5", 1999);
Car carObj2("Ford", "Mustang", 1969);
// Print values
cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n";
return 0;
}
就像函数一样,构造函数也可以在类外部定义。首先,在类内部声明构造函数,然后在类外部定义它,方法是指定类名,后跟作用域解析::运算符,后跟构造函数的名称(与类相同) :
- Example
class Car { // The class
public: // Access specifier
string brand; // Attribute
string model; // Attribute
int year; // Attribute
Car(string x, string y, int z); // Constructor declaration
};
// Constructor definition outside the class
Car::Car(string x, string y, int z) {
brand = x;
model = y;
year = z;
}
int main() {
// Create Car objects and call the constructor with different values
Car carObj1("BMW", "X5", 1999);
Car carObj2("Ford", "Mustang", 1969);
// Print values
cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n";
return 0;
}
C++ Access Specifiers
Access Specifiers
到目前为止,您已经非常熟悉出现在我们所有类示例中的 public
关键字:
- Example
class MyClass { // The class
public: // Access specifier
// class members goes here
};
public 关键字是访问说明符。访问说明符定义如何访问类的成员(属性和方法)。在上面的示例中,成员是公共的 - 这意味着可以从代码外部访问和修改它们。
但是,如果我们希望成员是私密的并且对外界隐藏怎么办?
在 C++ 中,存在三个访问说明符:
- public - 成员可以从类外部访问
- private - 无法从类外部访问(或查看)成员
- protected - 不能从类外部访问成员,但是可以在继承的类中访问它们。稍后您将了解有关继承的更多信息。
在下面的示例中,我们演示了公共成员和私有成员之间的差异:
class MyClass {
public: // Public access specifier
int x; // Public attribute
private: // Private access specifier
int y; // Private attribute
};
int main() {
MyClass myObj;
myObj.x = 25; // Allowed (public)
myObj.y = 50; // Not allowed (private)
return 0;
}
如果您尝试访问私有成员,则会发生错误:
注意:可以使用同一类中的公共方法来访问类的私有成员。请参阅下一章(封装)了解如何执行此操作。
提示:将类属性声明为私有(尽可能频繁)被认为是一种很好的做法。这将减少您自己(或其他人)弄乱代码的可能性。这也是封装概念的主要成分,您将在下一章中了解更多内容。
注意:默认情况下,如果不指定访问说明符,类的所有成员都是私有的:
class MyClass {
int x; // Private attribute
int y; // Private attribute
};
C++ Encapsulation
Encapsulation
封装的含义是确保“敏感”数据对用户隐藏。为此,您必须将类变量/属性声明为私有(无法从类外部访问)。如果希望其他人读取或修改私有成员的值,可以提供公共的 get 和 set 方法。
Access Private Members
要访问私有属性,请使用公共“get”和“set”方法:
- Example
#include <iostream>
using namespace std;
class Employee {
private:
// Private attribute
int salary;
public:
// Setter
void setSalary(int s) {
salary = s;
}
// Getter
int getSalary() {
return salary;
}
};
int main() {
Employee myObj;
myObj.setSalary(50000);
cout << myObj.getSalary();
return 0;
}
示例解释
工资属性是私人的,具有限制访问权限。
public setSalary()方法采用一个参数(s)并将其分配给薪金属性(薪金= s)。
public getalary()方法返回私人工资属性的值。
在main()内部,我们创建了员工类的对象。现在,我们可以使用setSalary()方法将私有属性的值设置为50000。然后,我们调用对象上的getalary()方法以返回值。
Why Encapsulation?
将类属性声明为私有(尽可能频繁地)被认为是一种很好的做法。封装可确保更好地控制您的数据,因为您(或其他人)可以更改代码的一部分而不影响其他部分
提高数据安全性
C++ Inheritance
Inheritance
在 C++ 中,可以将属性和方法从一个类继承到另一个类。我们将“继承概念”分为两类:
- 派生类(子类)- 从另一个类继承的类
- 基类(父类)- 继承自的类
要从类继承,请使用 : 符号。
在下面的示例中,Car 类(子类)继承了 Vehicle 类(父类)的属性和方法: - example
// Base class
class Vehicle {
public:
string brand = "Ford";
void honk() {
cout << "Tuut, tuut! \n" ;
}
};
// Derived class
class Car: public Vehicle {
public:
string model = "Mustang";
};
int main() {
Car myCar;
myCar.honk();
cout << myCar.brand + " " + myCar.model;
return 0;
}
C++ Multilevel Inheritance
Multilevel Inheritance
一个类也可以从一个已经从另一个类派生的类派生。
在以下示例中,MyGrandChild 派生自类 MyChild(派生自 MyClass)。
- Example
// Base class (parent)
class MyClass {
public:
void myFunction() {
cout << "Some content in parent class." ;
}
};
// Derived class (child)
class MyChild: public MyClass {
};
// Derived class (grandchild)
class MyGrandChild: public MyChild {
};
int main() {
MyGrandChild myObj;
myObj.myFunction();
return 0;
}
C++ Multiple Inheritance
Multiple Inheritance
一个类也可以从多个基类派生,使用逗号分隔的列表:
- Example
// Base class
class MyClass {
public:
void myFunction() {
cout << "Some content in parent class." ;
}
};
// Another base class
class MyOtherClass {
public:
void myOtherFunction() {
cout << "Some content in another class." ;
}
};
// Derived class
class MyChildClass: public MyClass, public MyOtherClass {
};
int main() {
MyChildClass myObj;
myObj.myFunction();
myObj.myOtherFunction();
return 0;
}
C++ Inheritance Access
Access Specifiers
您从“访问说明符”一章了解到,C++ 中提供了三个可用的说明符。到目前为止,我们只使用了 public(类的成员可以从类外部访问)和 private(成员只能在类内部访问)。第三个说明符 protected 与 private 类似,但也可以在继承类中访问:
- Example
// Base class
class Employee {
protected: // Protected access specifier
int salary;
};
// Derived class
class Programmer: public Employee {
public:
int bonus;
void setSalary(int s) {
salary = s;
}
int getSalary() {
return salary;
}
};
int main() {
Programmer myObj;
myObj.setSalary(50000);
myObj.bonus = 15000;
cout << "Salary: " << myObj.getSalary() << "\n";
cout << "Bonus: " << myObj.bonus << "\n";
return 0;
}
C++ Polymorphism
Polymorphism
多态性意味着“多种形式”,当我们有许多通过继承相互关联的类时,就会发生多态性。
就像我们在上一章中指定的那样;继承允许我们从另一个类继承属性和方法。多态性使用这些方法来执行不同的任务。这使我们能够以不同的方式执行单个操作。
例如,考虑一个名为 Animal 的基类,它有一个名为 AnimalSound() 的方法。动物的派生类可以是猪、猫、狗、鸟 - 并且它们也有自己的动物声音实现(猪叫声和猫喵叫声等):
- Example
// Base class
class Animal {
public:
void animalSound() {
cout << "The animal makes a sound \n";
}
};
// Derived class
class Pig : public Animal {
public:
void animalSound() {
cout << "The pig says: wee wee \n";
}
};
// Derived class
class Dog : public Animal {
public:
void animalSound() {
cout << "The dog says: bow wow \n";
}
};
请记住,在“继承”一章中,我们使用 : 符号从类继承。
现在我们可以创建 Pig 和 Dog 对象并重写 AnimalSound() 方法:
- Example
// Base class
class Animal {
public:
void animalSound() {
cout << "The animal makes a sound \n";
}
};
// Derived class
class Pig : public Animal {
public:
void animalSound() {
cout << "The pig says: wee wee \n";
}
};
// Derived class
class Dog : public Animal {
public:
void animalSound() {
cout << "The dog says: bow wow \n";
}
};
int main() {
Animal myAnimal;
Pig myPig;
Dog myDog;
myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
return 0;
}
为什么以及何时使用“继承”和“多态”?
- 它对于代码可重用性很有用:创建新类时重用现有类的属性和方法。