Windows程序设计读书笔记(Windows与面向对象)
想写这个题目已经很久了,一直没有能够完整的整理出来,每次开头总是思路漂移,最后不得不停笔.今天终于想通了一点,先整理整理.
-------------抽象的问题-----------------------------------
先问一个问题,你见过的程序中,那个软件是面向对象的思想体现的最成功的?
我的答案是:Windows系统.
windows系统无疑是计算机行业的一个奇迹.正是由于windows操作系统的出现,才使得计算机的广泛普及成为可能,使得计算机由一个高科技变成了家用电器.譬如在我们家,我父亲快60岁了,他不懂英文,不怎么会用我们家的有线机顶盒,也不怎么会用DVD(都接在一个电视机上,需要来回接线),可是他会用电脑,经常上网看看新闻.对于他来说,电脑要比其他家用设备更加容易使用,也更加经常使用.
Windows成功的关键因素是什么呢?容易使用.
从技术上讲,为什么容易使用呢? 答案是: 抽象.
譬如,你打开电脑以后,Windows启动了,第一个界面是: 桌面.
请仔细想一下,这个桌面是真实的还是虚拟的?他是需拟出来的.更准确的说,你看到的是一幅图象,是Windows系统在屏幕上画出来的一幅图象.在现实生活中,并不存在这样一个实际的桌面,上面摆着各种文件,文件夹.这些都是系统用图形化的方式虚拟出来的.在物理上,他们都是硬盘上的磁介质,用不同的排列方式来代表的.
这个就是抽象.把原本难以理解,难以描述的事物,通过转换成理解范畴内的,可以类比的事物来进行描述和理解.
不过很有意思的是,当这种抽象或者类比被广泛使用以后,人们往往忽视他的存在.在很多人看来,桌面似乎已经是物理的,而不是虚拟的了.Windows能够做到这个程度,就是非常成功的了.
再想一下,Windows系统里面,几乎所见的一切,都是抽象的产物.
譬如:文件和文件夹.这些在物理上都是磁介质,被虚拟成文件夹,里面存着文件.
本地磁盘.物理上实际上是一块硬盘,被虚拟成多个不同的磁盘.
这种转换,有时比较明显,有时不那么明显,但实际上当你使用Windows时,这种抽象和转换几乎无处不在.
似乎扯的很远了,好了现在回到主题上来.
下一个问题:Windows是面向对象的吗?答案似乎不那么肯定.
面向对象的定义,各家有各家的说法,似乎没有统一的标准.一般涵盖抽象,封装,继承,多态等多个方面.具体的定义我就不抄书本了.
抽象就不用说了,上面已经论述过,Windows是一个非常成功的抽象产品.
---------------封装的问题-----------------------------------
下面谈谈封装.
一般来说,封装指的是把数据和对数据的操作放到一起的方式.这个在Windows里面,尤其在底层的API提供上,有相对应关系的只有结构体了.Windows本身定义了大量的结构体数据结构,调用API的时候需要提供相应的结构体引用.
但是且慢下结论.让我们来看一个基本的Windows程序.每个Windows窗体类型都带有一个回调函数.定义如下:
Java代码
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);在这个函数内部,也会定义很多的内部数据,这些内部数据也是不可能在外面直接访问到的,这算不算是封装呢?
word文件,你只能通过Word程序打开,否则无法正常读取写入,这算不算是封装呢?
这个问题先放一放,一时讨论不清楚.
----------------继承的问题-------------------------------------------
继承的问题要好说一些.Windows打开的每个窗口,都有标题,菜单,状态栏,最小化,最大化,都可以拖动,缩放.这些不都是从一个基本的windows窗口应该具有的特征上继承下来的吗?如果不是这样的话,每个程序都需要自己处理这些事情,岂不要疯掉了.
顺便说一下,Windows是如何做到这些工作的呢?他不是通过定义一个通用的Window类,然后每新建一个窗口,从下面继承一个,从而得到一个默认的处理方法.而是通过下面的代码显式调用API函数来实现的:
Java代码
switch(message)
{case WM_CREATE:
//do somthing
return 0;
case WM_DESTROY:
//do something
return 0;
}
//在switch没有到达的情况下,调用默认的处理方法
return DefWindowProc(hwnd,message,wParam,lParam);
switch(message)
{case WM_CREATE:
//do somthing
return 0;
case WM_DESTROY:
//do something
return 0;
}
//在switch没有到达的情况下,调用默认的处理方法
return DefWindowProc(hwnd,message,wParam,lParam);
通过这种方式,这个新定义的窗口,就具有了windows标准窗口的一切功能,包括最大化,最小化,移动,改变大小等等.
从逻辑上上讲,这个新创建的窗口完全 继承 了标准窗口的一切功能.
在具体实现上,他的实现方式是把标准窗口的所有功能集成在一个DefWindowProc函数中,通过调用这个函数来实现对通用功能的继承.
------------多态的问题------------------------
多态的问题相对容易一些.Windows里面的程序有无数的窗口,每个有着类似的外观,类似的布局,但其中每个应用程序的具体功能,界面,位置,大小都各不相同.
这正是标准的多态定义,针对同样的操作,例如点击一下,不同的窗口反应自然是不一样的了.
------------小结-----------------------------
综上所述,我的观点是,Windows系统本身是一个极好的面向对象思想体现的范例.但奇怪的是,在我见过的所有讲述面向对象的书里面,好象从来没有把windows当成例子来描述面向对象思想和实例的.
------------消息机制--------------------------
再引申引申,采用面向对象思想设计和实现系统以后,系统中有了很多很多的对象,这些对象之间是如何通讯的呢?标准的说法是:通过发送消息来通讯,我发给你一个消息,你发给我一个消息.而消息通讯,正是Windows系统的核心特征所在.在Windows系统中,每个应用程序都有自己的消息队列,主程序最后会进入消息处理中,从队列中取出消息来进行一一处理.而Windows系统本身也可以直接调用应用程序的消息处理程序,或者放入消息队列一条特定消息.
各个应用程序之间也可以相互发送消息给对方,放到对方的消息队列中中.
而最特别的一点是:所有发送的消息,格式居然是一致的!!!
也就是说,在Windows系统中,所有传来传去的消息,包含的信息量居然是一致的.这些信息量就是WndProc的四个参数:hwnd,message,wParam,lParam.每个长度是32bit,总共128bit的消息,就能够把整个windows系统全部运行起来了.
奇迹,完全是奇迹!!!