目录
谈面向对象(Object-oriented)
“面向对象”是的观念是描绘世界用的,所以,你可以用真实生活中的经验去思考程序设计的逻辑。人是一个对象,人有眼睛、鼻子、耳朵。。。这些是他的属性,人可以走、可以跑、可以吃饭。。。这些也是属性。地球是一个对象,地球中又有许多对象。。。
面向对象中的抽象可以理解为共性。
谈封装
封装指的是屏蔽具体的细节,只提供实现的接口。函数就是一种封装,你只要调用改该函数就可以实现功能,而不需要去关心功能是如何实现的。类是比函数更高级的封装,它中提供了三个成员修饰符来控制成员的访问权限:
1.public //成员可以在类中以及类外使用
2.private //成员只能在类中使用
3.protected //成员在类中及其子类中可以使用
数据抽象和封装的好处
1. 避免类内部出现无意的、可能破坏对象状态的用户级错误。
2. 随时间推移可以根据需求改变或缺陷(bug)报告来完善实现,而无需更改用户及代码。
谈继承
什么是继承
“继承”是面向对象软件技术当中的一个概念。如果一个类A继承自另一个类B,就把这个A称为"B的子类",而把B称为"A的父类"。继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。
继承的好处
1. 可以重用代码。
在同一个行业中,他们各业务流程往往有很大的相似性,但往往我们都是到一个项目中就重新写一套流程代码,或者粘贴以前的代码.可能有很多代码都是以前写过的重复代码.造成重复劳动.如果采用继承应该这样,首先在父类中做一个基本上大部分行业项目都必要的简洁的主流程.在子类中针对具体项目的特殊性做主流程充分的完善的补充.这样在每个项目中,只针对项目的特殊性编写代码,大大降低重复劳动.当然根据具体流程的复杂多可以划分多的继承层次,呈现一种继承的树结构,但一定的要保证层次一定要有实际的意义.
2. 多态。
谈多态(Polymorphism)
以相同的的指令去调用了不同的函数,这就是多态。多态靠虚函数来实现
两个概念:
后期绑定或动态绑定:编译器无法再编译时期不断到底调用哪一个函数,必须在执行期才能判断之。
前期绑定或静态绑定:非虚函数在编译时期就转换为固定地址的调用了。
多态的目的是要让处理“基类之对象”的程序代码,能够完全无障碍地继续处理“派
类之对象”。
谈虚函数
虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。
Upcasting(向上强制转换)将会造成对象的内容被切割(Object slicing) P70
#include "stdafx.h"
#include <iostream>
class CShape
{
private:
int m_color;
public:
CShape() {m_color = 0;}
virtual void display() = 0; //纯虚函数,抽象类不需要实现该函数
~CShape() {}
};
class CRect : public CShape
{
private:
int m_length,m_width;
public:
CRect()
{
m_length = 0;
m_width = 0;
}
~CRect() {}
virtual void display()
{
std::cout<<"CRect"<<std::endl;
}
};
class CCircle : public CShape
{
private:
int m_radius;
public:
CCircle()
{
m_radius = 0;
}
~CCircle() {}
virtual void display()
{
std::cout<<"CCircle"<<std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CRect rect;
CCircle circle;
CShape *shape[2] = {
shape[0] = &rect,
shape[1] = &circle
};
for(int i = 0;i < 2;i++)
{
shape[i]->display();
}
return 0;
}
谈this指针
class CRect : public CShape
{
private:
int x,y;
public:
void display()
{
}
};
CRect rect1,rect2;
rect1.Setcolor(1);
rect2.Setcolor(2);
编译器实际上为你做出来的代码是
CRect::Setcolor(1,(CRect*)&rect1);
CRect::Setcolor(2,(CRect*)&rect2);
不过CRect本身并没有声明Setcolor,它是从CShape中继承来的,所以编译器实际产生的代码是
CRect::Setcolor(1,(CRect*)&rect1);
CRect::Setcolor(2,(CRect*)&rect2);
class CShape
{
...
public:
void Setcolor(int color)
{
m_color = color;
}
};
被编译器编译之后,其实是:
class CShape
{
...
public:
void Setcolor(int color,(CShape*)this)
{
this->m_color = color;
}
}