找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3774|回复: 7

【面向对象】面向对象是一种思想,而不是一种编程语言

[复制链接]

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
发表于 2014-8-24 22:11:25 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
几乎任何语言都可以面向对象。汇编也可以。

我认为:把不同的事物,用编程语言描述清楚,然后对它们进行组织调用,就是面向对象。并不一定非得是C++的那种形式,任何语言都可以面向对象。
面向对象并不是把数据重新用结构体进行打包,而是把事物当成对象来看待。比如“向量”,就把它看成对象,对向量进行运算的程序专门写,而不是在用到向量的地方用float来表示。比如这样:
  1. typedef struct
  2. {
  3.     float x,y,z;
  4. }Vector3,*Vector3P;
复制代码
这里定义了一个三维向量。这是对象吗?是的。而非面向对象的编程思路是什么呢?就像下面这样:
  1. float x,y,z;
复制代码
当然这个也可以被当成对象来编程,但是真正有说服力的是下面的代码。
  1. //代码演示:判断一个三维空间中的点是否在一个立方体的内部

  2. //=============================================================================
  3. //面向对象的思想
  4. //-----------------------------------------------------------------------------
  5. #include<math.h>
  6. #include<memory.h>

  7. //三维向量
  8. typedef struct
  9. {
  10.     float x,y,z;
  11. }Vector3,*Vector3P

  12. //四维向量
  13. typedef struct
  14. {
  15.     float x,y,z,w;
  16. }Vector4,*Vector4P;

  17. //三阶矩阵
  18. typedef struct//矩阵可以当成“坐标系”来看待
  19. {
  20.     Vector3 xAxis;
  21.     Vector3 yAxis;
  22.     Vector3 zAxis;
  23. }Matrix3x3,*Matrix3x3P;

  24. //立方体
  25. typedef struct
  26. {
  27.     Vector3     vSize;//长宽高
  28.     Matrix3x3   mRotation;//旋转
  29.     Vector3     vPosition;//位置
  30. }Box3,*Box3P;

  31. //向量乘三阶矩阵的函数
  32. void Vec3MulTransposedMatrix3x3(Vector3P pVOut,Vector3P pVIn,Matrix3x3P pMatrix);

  33. //=====================================
  34. //判断点是否在立方体内部的函数
  35. //是返回非零,否返回零
  36. //-------------------------------------
  37. int IsPointInBox
  38. (
  39.     Vector3P    pPoint, //点
  40.     Box3P       pBox    //立方体
  41. )
  42. {
  43.     Vector3     vTransformed;
  44.    
  45.     vTransformed.x=pPoint->x-pBox->vPosition.x;//相对坐标
  46.     vTransformed.y=pPoint->y-pBox->vPosition.y;
  47.     vTransformed.z=pPoint->z-pBox->vPosition.z;
  48.    
  49.     Vec3MulTransposedMatrix3x3(&vTransformed,&vTransformed,&(pBox->mRotation));//变换坐标位置
  50.    
  51.     if( fabs(vTransformed.x)<=pBox->vSize.x &&//如果经过变换的顶点在立方体内部
  52.         fabs(vTransformed.y)<=pBox->vSize.y &&
  53.         fabs(vTransformed.z)<=pBox->vSize.z)
  54.         return 1;//返回非零
  55.     else
  56.         return 0;
  57. }

  58. //顶点乘三阶矩阵的函数
  59. void Vec3MulTransposedMatrix3x3(Vector3P pVOut,Vector3P pVIn,Matrix3x3P pMatrix)
  60. {
  61.     Vector3 vTemp=
  62.     {
  63.         pVIn->x*pMatrix->xAxis.x+pVIn->y*pMatrix->xAxis.y+pVIn->z*pMatrix->xAxis.z,
  64.         pVIn->x*pMatrix->yAxis.x+pVIn->y*pMatrix->yAxis.y+pVIn->z*pMatrix->yAxis.z,
  65.         pVIn->x*pMatrix->zAxis.x+pVIn->y*pMatrix->zAxis.y+pVIn->z*pMatrix->zAxis.z
  66.     };
  67.     memcpy(pVOut,&vTemp,sizeof(Vector3));
  68. }

  69. //=============================================================================
  70. //面向过程的思想
  71. //-----------------------------------------------------------------------------
  72. #include<math.h>
  73. #include<memory.h>

  74. //=====================================
  75. //判断点是否在立方体内部的函数
  76. //是返回非零,否返回零
  77. //-------------------------------------
  78. int IsPointInBox
  79. (
  80.     float   px,         //点
  81.     float   py,
  82.     float   pz,
  83.     float   bx,         //立方体位置
  84.     float   by,
  85.     float   bz,
  86.     float   mxx,        //立方体旋转矩阵
  87.     float   mxy,
  88.     float   mxz,
  89.     float   myx,
  90.     float   myy,
  91.     float   myz,
  92.     float   mzx,
  93.     float   mzy,
  94.     float   mzz,
  95.     float   sizex,      //立方体尺寸
  96.     float   sizey,
  97.     float   sizez
  98. )
  99. {
  100.     float tpx,tpy,tpz;//变换后的点
  101.    
  102.     px-=bx;//点相对立方体中心位置的点
  103.     py-=by;
  104.     pz-=bz;
  105.    
  106.     tpx=px*mxx+py*mxy+pz*mxz;//取得点实际相对立方体位置的点
  107.     tpy=px*myx+py*myy+pz*myz;
  108.     tpz=px*mzx+py*mzy+pz*mzz;
  109.    
  110.     if( fabs(tpx)<=sizex &&//如果经过变换的顶点在立方体内部
  111.         fabs(tpy)<=sizey &&
  112.         fabs(tpz)<=sizez)
  113.         return 1;//返回非零
  114.     else
  115.         return 0;
  116. }
复制代码
面向对象并不仅仅是将数据打包做成结构体给函数使用,关键是,我们把三维向量,用Vector3来表示,而不是用float x,y,z;来表示。我们把它看作是三维向量,并针对它进行编程。这才是面向对象的思想。

面向对象的好处是代码的可复用性高,可读性高,便于管理,你看上面的矩阵、向量的结构体和辅助函数等就可以拿去别的地方使用。而面向过程的要复用就麻烦多了。
实际上汇编也可以面向对象。。事实上绝大多数语言都可以面向对象。

这个时候可能会有人提出异议:假设我有个使向量单位化的函数Normalize,我定义void Normalize(Vector3*pVec);和我定义Vector3::Normalize();是有本质区别的,因为前者是调用别的函数来完成向量单位化,而后者是向量自己把自己单位化了。前者仍然是面向过程的思想,而后者才是真正的面向对象。
对此,我认为这只是一个形式上的区别。最终编译到二进制的时候,这两者的实现方式大同小异。
那么从语义上呢?
void Normalize(Vector3*pVec);确实是调用别的函数来完成向量单位化,有“面向过程”的嫌疑,但是反过来想,对于C语言,这样已经是最接近“面向对象”思想的写法了。
比起C++,C语言的优势很多。兼容性好,可移植性好,透明度高,都是它的优势。

有关C语言面向对象的实际应用,请大家参看libpng、libjpeg、giflib、libmp3、libFLAC、zlib、7z、lzma、freetype等各种国际开源项目的源码。
回复

使用道具 举报

0

主题

31

回帖

109

积分

用户组: 小·技术宅

UID
141
精华
0
威望
2 点
宅币
74 个
贡献
0 次
宅之契约
0 份
在线时间
10 小时
注册时间
2014-3-23
发表于 2014-9-3 15:33:28 | 显示全部楼层
原本的面向过程编程 是向函数传递结构体指针 让一个函数可以为同一结构体的多个变量服务
面向对象只不过是编译器做了这步 本质还是面向过程 将结构体理解成对象的数据 然后偷偷的把this指针用第一个参数传给成员函数了 也就是所有成员函数其实都带有一个隐藏参数
不过面向对象的基本特征不是那么好模拟的 继承和多态 不是面向过程语言简单就能做到的
这也就是人家说的 c++ java 才能真正的面向对象了...
回复 赞! 靠!

使用道具 举报

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
 楼主| 发表于 2014-9-3 16:57:21 | 显示全部楼层
我晕 发表于 2014-9-3 07:33
原本的面向过程编程 是向函数传递结构体指针 让一个函数可以为同一结构体的多个变量服务
面向对象只不过是 ...

这是你对面向对象的定义吧?
个人觉得Linux的源码就是面向对象的。
回复 赞! 靠!

使用道具 举报

0

主题

31

回帖

109

积分

用户组: 小·技术宅

UID
141
精华
0
威望
2 点
宅币
74 个
贡献
0 次
宅之契约
0 份
在线时间
10 小时
注册时间
2014-3-23
发表于 2014-9-3 17:29:06 | 显示全部楼层
0xAA55 发表于 2014-9-3 16:57
这是你对面向对象的定义吧?
个人觉得Linux的源码就是面向对象的。

呵呵 我对面向对象的定义? 这应该算业内的看法吧
好吧 那你可以说每个人的定义都不同...

Linux的源码我只在下载时翻了一下 根本没看过 不过我觉得你这句话我应该能认同 的确有很多代码 看上去立刻就有一种感觉 应该就是你说的面向对象了
回复 赞! 靠!

使用道具 举报

0

主题

2

回帖

21

积分

用户组: 初·技术宅

UID
558
精华
0
威望
1 点
宅币
17 个
贡献
0 次
宅之契约
0 份
在线时间
1 小时
注册时间
2014-11-17
发表于 2014-11-21 14:13:35 | 显示全部楼层
额,其实我想说楼主的理解还是面向过程并没有面向对象。面向对象的最起码要具备三个特性,封装,继承和多态。就拿封装这一条来说,什么是封装?就是把数据和在数据上的操作封装起来,这就是一个对象,也就是说对象需要具有能对其自身进行操作的能力。比如在C++中定义一个struct Vector3D { float x; float y; float z;}; 假如现在要对这个向量规范化,那么可能会需要一个函数比如 void Normal(Vector3D &vec3D); 这就是早期的函数库思想,C语言中很多类似这样的库,这就是一种面向过程的思想。如果是面向对象,那么Vector3D中就应该包含对自身进行规范化的函数(我想不用多说,C++的struct是可以定义函数的),结果就是struct Vector3D {float x; float y; float z; void Normal(){函数定义} };,这样以后如果建立一个对象 Vector3D vec3D; 直接调用这个对象的函数 vec3D.Normal();就完成了规范化,这就是面向对象。当然封装的内容不仅仅这么多,继承和多态我就不说了,反正楼主所说的还是停留在面向过程阶段。
回复 赞! 靠!

使用道具 举报

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
 楼主| 发表于 2014-11-21 14:20:40 | 显示全部楼层
sizz 发表于 2014-11-21 14:13
额,其实我想说楼主的理解还是面向过程并没有面向对象。面向对象的最起码要具备三个特性,封装,继承和多态 ...


那就是形式上的区别喽?你让我想起了COM类这种不伦不类的东西,如果让C语言使用,这个应该算面向对象还是面向过程呢?

此外多态可以通过转换结构体指针,使用union来实现,而继承也是如此。
另外如果要C语言实现你说的那种特性,那也可以,使用一些宏即可。
回复 赞! 靠!

使用道具 举报

0

主题

2

回帖

21

积分

用户组: 初·技术宅

UID
558
精华
0
威望
1 点
宅币
17 个
贡献
0 次
宅之契约
0 份
在线时间
1 小时
注册时间
2014-11-17
发表于 2014-11-21 14:35:43 | 显示全部楼层
这不是形式上的区别,那我们换个角度说,如果楼主你上面定义的Vector3结构体假如在某个编译器中已经被实现为一种基本类型,就和int bool float这类一样的基本类型,那么楼主帖子中两个函数实现又有什么区别呢,都是对基本类型的操作而已。其模式开始“用一个函数去操作另一个对象”,而不是“对象对自身进行操作”,这就是本质区别。
回复 赞! 靠!

使用道具 举报

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
 楼主| 发表于 2014-11-21 14:40:26 | 显示全部楼层
sizz 发表于 2014-11-21 14:35
这不是形式上的区别,那我们换个角度说,如果楼主你上面定义的Vector3结构体假如在某个编译器中已经被实现 ...


从汇编的角度来看,“用一个函数去操作另一个对象”和“对象对自身进行操作”是一样的。
面向对象是一种思想而不是一种编程语言。请仔细看原文。
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-3-29 03:52 , Processed in 0.041118 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表