面向对象(一)
简述面向对象
- 概念:面向对象是一种编程思想,把一切东西看成一个个对象,将对象的属性行为等打包成一个类来表示
- 面向对象和面向过程区别
- 面向过程:根据业务逻辑从上往下写代码
- 面向对象:把整个需求按照特点,功能进行划分,将存在共性的部分封装成类,减少了重复代码的重写过程
面向对象三特征
-
封装
- 概念:将数据和方法进行有机结合,隐藏对象的属性以及实现细节,仅对外提供公开接口和对象进行交互
-
继承
- 概念:可以使用现有类的所有功能,无需重写原来的类就能对这些功能进行扩展
- 写法实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// 派生类
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
|
继承方式 |
private 继承 |
protected 继承 |
public 继承 |
基类的private 成员 |
不可见 |
不可见 |
不可见 |
基类的protected 成员 |
变为private 成员 |
仍为protected 成员 |
仍为protected 成员 |
基类的public 成员 |
变为private 成员 |
变为protected 成员 |
仍未public 成员 |
-
多态
- 概念:用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数,调用成员函数时,会根据函数的对象类型来执行不同的函数,
- 实现方式:重写,重载
- 举例
1
2
3
4
5
6
7
8
9
10
11
12 | Rectangle rec(10,7);
Triangle tri(10,5);
// 存储矩形的地址
shape = &rec; // 父类型指针指向子类实例
// 调用矩形的求面积函数 area
shape->area();
// 存储三角形的地址
shape = &tri;
// 调用三角形的求面积函数 area
shape->area();
|
C++重写与重载
-
重写
- 派生类中重写定义的函数,其参数列表,函数名,返回参数类型都与基类被重写函数相同,只有函数体不同,派生类调用函数时会调用派生类的重写函数,而不会调用被重写函数,重写和被重写函数前需要有
virtual
修饰
- 举例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | #include<bits/stdc++.h>
using namespace std;
class A {
public:
virtual void fun() { cout << "A"; }
};
class B :public A { //继承
public:
virtual void fun() { cout << "B"; } //函数重写
};
int main(void) {
A* a = new B(); a->fun();//输出B,A类中的fun在B类中重写
}
|
-
重载
- 在同一个作用域,声明几个功能类似的同名函数,但是这些函数的形参需不同,更具参数列表可确定调用那个函数
- 举例
| #include<bits/stdc++.h>
using namespace std;
class A {
void fun() {};
void fun(int i) {};
void fun(int i, int j) {};
void fun1(int i,int j){};
};
|
C++构造函数
默认构造函数,初始化构造函数,拷贝构造函数,移动构造函数
| class Student {
public: //默认构造函数 Student() { num=1001; age=18; }
}
|
| class Student {
Student(int n,int a):num(n),age(a){}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | #include<iostream >
using namespace std;
class Complex
{
public:
double real, imag;
Complex(double r, double i) {
real= r; imag = i;
}
};
int main(){
Complex cl(1, 2);
Complex c2 (cl); //用拷贝构造函数初始化c2
cout<<c2.real<<","<<c2.imag; //输出 1,2
return 0;
}
|
只定义析构函数,会自动生成哪些构造函数
默认构造函数和拷贝构造函数
一个类默认生成哪些函数
| run& operator = (const run& copy) {}
|
C++类对象的初始化顺序以及多重继承下的顺序
- 父类构造函数>成员类构造函数>自身构造函数
- 析构函数相反
- 成员变量的初始化顺序与变量在类中声明顺序有关
- 构造函数的调用顺序是类派生表中的顺序
向上转型和向下转型
- 向上转型:子类转换为父类,相对安全
- 向下转型:父类转换为子类,不安全
- 原因:父类的指针或引用的内存中不一定包含子类成员的内存