作者:暮迟_MCz_P | 来源:互联网 | 2023-10-11 03:08
好了,现在我要给大家讲讲面向对象的一些知识。上次说到了,面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。一般地,面向对象具有继承性、封装性、多态性三个特征。
好了,现在我要给大家讲讲面向对象的一些知识。上次说到了,面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。一般地,面向对象具有继承性、封装性、多态性三个特征。
举个简单的例子吧,现在我让你去用计算器计算3*4的结果,你会这么做呢?仔细想想,流程应该如下。
(1)买一个计算器;
(2)输入3*4;
(3)按下=键,获得结果。
这正好对应这三行代码:
(1)Calculator c;
(2)c.inputFormula(“3*4”);
(3)c.getResult();
所以说,面向对象与现实非常贴合,这就是面向对象受欢迎的原因之一。
有人又会疑惑了,我怎么知道计算器对象具有哪些函数呢,函数的参数扫是什么,返回值又是什么?有没有一个标准或者是文档呢?
很负责的告诉你,有的。计算器有说明书,面向对象就有API。API:application Programming Interface,应用程序编程接口。
例如,这里的计算器类的API如下所示:
根据这个API,我们可以随心所欲地使用计算器啦~
然后有人又有疑惑了,你的API中为什么setFormula()函数要重载呢?为什么接收C++的字符串之外还要写一个接收C风格的字符串呢?
这其实就是面向对象的多态性。通俗一点说,就是多种选择随我选。一个面向对象的优质代码,往往就是尽可能多给与对方(使用者)更多的选择。
此外我再通俗地说一下封装性:即内部存储和实现不关我的事。例如在计算器类中,getResult()函数是如何工作的,这个或许是字符串解析吧,或许是利用栈结构,或许是递归……反正我是不知道,也没有必要知道,我只要会用就行了。就好像我们买电视,没有人说一定要知道电视的结构、组成才能看电视吧。面向对象也是一样的原理。
最后则是面向对象的继承性。例如:
(派生)人→学生→研究生
(继承)研究生→学生→人
就是典型的一个继承。
我们写三个类(人、学生、研究生)的“恋爱”方法吧。
class Person {
int age;
void love()
{
cout<<"fall in love at will"<
class Student:public Person
{
int age;
void love()
{
cout<<"fall in love seriously"<
class Postgraduate:public Student
{
int age;
void love()
{
cout<<"fall in love maturely"<
总而言之,这三类人是“随心所欲的恋爱”,“认真的恋爱”,“成熟的恋爱”。如果这个时候定义一个研究生对象gth,调用“恋爱”方法后,输出的肯定是“成熟的恋爱”。
Postgraduate gth;
gth.love();
这个就称为方法(函数)覆盖(重写)。当然这里的覆盖并不是指一定访问不到了,只是使用起来好像是访问不到了。如果想要完全覆盖,需要使用虚函数。这里就不再赘述。
下面的概念很有趣。对于自然界很多物体(具体的或抽象的),一般都可以建立对象(实例化)。但是,对于一部分概念,其一般为一类统称,一般不希望其实例化,例如水果、动物、蔬菜……例如,“xxx,给我拿一个水果来。”这句话其实就是有问题的。
但是,“水果”作为一个概念,的确拥有一些属性(例如VC含量,重量)和方法(吃、存储)等。所以我们希望定义一个类,其指定了一部分属性和方法(方法空实现),该类不可实例化,只能通过继承后再实例,达到自然界的高度仿真。
我们需要纯虚函数来实现这个规律。
我们先写水果类:
class Fruit
{
private:
double vcContent;
double weight;
public:
virtual void eat()=0;
virtual void store()=0;
};
再写苹果类:
class Apple:public Fruit
{
public:
void eat()
{
cout<<"just eat it :)"<void store()
{
cout<<"stored in shadow"<
最后是main()函数
void main()
{
Apple apple;
apple.eat();
apple.store();
}
最后,我们来一个生动的实战例子,来说明面向对象是如何编程的。
NOJ实战 1058
Tom和Jerry在10*10的方格中:
……..
……*…
……..
……….
…*.C….
…..…
…*……
..M……*
….….
..……
C=Tom(猫)
M=Jerry(老鼠)
*=障碍物
.=空地
他们各自每秒中走一格,如果在某一秒末他们在同一格中,我们称他们“相遇”。注意,“对穿”是不算相遇的。
他们移动方式相同:平时沿直线走,下一步如果会走到障碍物上去或者出界,就用1秒的时间做一个右转90度。一开始他们都面向北方。
编程计算多少秒以后他们相遇。
我们简要的对这个现实世界的产物进行抽象和建模:
然后我们回想,为什么位置和方向都是向量呢?看下面一张图就能明了。
接下来,我们就可以进行代码的编写工作啦~
#include
#define LENGTH 10
using namespace std;
class Vector
{
private:
int x,y;
public:
Vector()
{
x=y=0;
}
void setX(int x)
{
this->x=x;
}
void setY(int y)
{
this->y=y;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
void setUp()
{
setX(-1);
setY(0);
}
void setDown()
{
setX(1);
setY(0);
}
void setLeft()
{
setX(0);
setY(-1);
}
void setRight()
{
setX(0);
setY(1);
}
bool operator==(Vector v)
{
return getX()==v.getX() && getY()==v.getY();
}
void output()
{
cout<<"("<","<")"<
最后我们进行一个小结:
浅谈ACM盲区:
1.界面友好
2.编程规范
(1)变量和函数的命名规范
(2)变量和函数的命名格式(驼峰式)
(3)缩进
(4)注释:尽量用英文来保证兼容性
(5)可移植性、函数封装与模块耦合
3.非实用方法
4.实用性编程
5.面向对象编程