科学网

 找回密码
  注册

tag 标签: 面向对象

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

面向对象:情人节快乐!
热度 1 jizx971 2017-2-14 08:46
爱情需要封装(private),亲情需要继承(extends),友情需要实现(implements)。 其实,爱情、亲情和友情,就在你的身边,而不是你的对面,你对面的那是别人的幸福。 不要左顾右盼,守好你的身边。 ——情人节快乐!20170214.
个人分类: 生活其他|1064 次阅读|1 个评论
面向对象(一)
qishi821 2016-6-29 10:35
近来有时间,想学些自己想学的,觉得自己应该学的一些东西。 面向对象(C++Java) 1. 何为抽象?(抽出像的东西) 软件设计的难度随着问题的规模和复杂程度而不断加大,抽象是人类在认识复杂现象的过程中使用的最强有力的方法。人们通过实践认识到,现实世界中的事物、状态或过程之间总存在着某种共性。把这些共性集中和概括起来,暂时忽略他们之间的差异,这就是 抽象 。即抽象就是抽出事物的本质特征而忽略它们的细节。 2. 何为程序? 由于人类的思维能力的限制,面对复杂问题,是不可能做出精确思维的。一般处理复杂系统总是将注意力集中在某一层次上考虑,采用层次构造和层次分析的方法分析它。因此我们说软件设计过程应该是在不同抽象级别考虑和处理问题的过程。最初,应在最高抽象级别上面使用问题域的语言叙述“问题”,以概括的方式叙述“问题解”,然后不断的具体化,不断地用面向过程的语言描述问题,最后在最低层抽象级别上给出可直接实现的“问题解”,即 程序 。 3. 业务建模 是以软件模型方式描述企业管理和业务所涉及的对象和要素以及它们的属性、行为和彼此关系,业务建模强调以体系的方式来理解、设计和构架企业信息系统。 业务建模是需求分析中最初试的阶段,也就是整个项目的初始阶段。需要指出的是,业务建模时间的跨度在不同的项目中有很大的差别的。在有些项目中,例如大型 ERP 系统,可能需要几个月的时间。而对于普通的项目,业务建模的时间可能仅仅需要几天的时间,也有的忽略这一阶段,或是以有限的方式执行。 4. 需求 是技术无关的。在需求阶段讨论技术是没有任何意义的,只会分散注意力。技术和实现细节是在后面的分析、设计阶段才需要考虑的事情。而在业务建模阶段,不但需要保证需求的技术无关性,还要保证需求不雅深入细节,因为在业务建模阶段,最重要的事情就是要了解业务的全貌,深入细节会浪费时间和精力。要知道,讨论一个企业里的业务细节,就算花费一个月也未必能够结束。 5. 建模 是软件开发中用到的基本工具之一,建模时了解建模的重要性和模型的作用是很必要的。模型是对一个系统的一些描述,可能是像大楼设计图一样,也可能是像建筑物施工图对大楼的详细描述,还可能是某种原型,例如同大楼的立体模型。模型是软件系统构建中一个必要的部分,在构建开始前,除了很琐碎的开发以外的所有开发都会包含建模。在任何软件开发的方法学中,任何一个阶段的输出都是一个模型的集合,并用作后续阶段的输入。统一建模语言是对模型表示的符号系统,已经成为当今建模广泛使用的标准。 模型是什么呢? 模型不是它所描述的事物,而是对这些事物的表示。但是,在某些实际的感觉中,它看起来就像是所描述的事物,任何一门学科中几乎都能找到模型。设计师有大量不同的建筑模型,比如设计图和蓝图。工程师有桥梁的模型,包括图纸和数学模型。城市规划师有街道布局的图纸和模型。政府规划人员提供像医院这样复杂的可能涉及金融和社会的模型。当然,在建立系统之前,计算机系统开发人员要构建系统模型。 我们为什么要建模呢? 是因为建模会比建造真实的事物更容易也更廉价,或者是因为实际的事物难于实现。一个设计者给一幢房屋草拟设计图,以便让购买者在建造之前就看到设计样式 -- 当发现购买者不喜欢这样的布局之时,在设计图纸上花费一千多元远比在建筑上花费十多万元要好得多。因为在构建一个模型时,与建设阶段相比,建模阶段所遇到的问题会更容易解决。例如在建桥之前,工程师能够在一个模型上计算出压力并选择合适的建筑材料,而不是建造一座桥来观察它是否能够承载负荷。同理,在两个小组合作构建软件系统的不同部分时,他们需要一些计划来确保不同的部分能够相互结合在一起。 模型在信息传递、信息交流的过程中起着非常重要的作用 ,一个复杂的大型系统建设需要很多小组、很多人员共同工作,如果他们按照能够相互结合的模型工作,那么,他们制造出来的产品也能够结合起来。另一方面,模型被用来描述你想要的东西,在软件开发中,有很多角色和责任,项目成员和项目外系统的各类用户之间的信息交流,对于项目的成功是极为重要的。 模型对计划也十分有用 。当知道了事物是如何组合的,需要完成什么,就能开始筹划构建过程了。此外,还需要模型来应对变化,如果某个人想要为一栋大的建筑重新布局,就需要一张已布线路的图纸。在软件开发过程中,一个阶段的输出通常是一个模型,这个模型又用于另一个阶段的输入。 模型并不总是必需的 。有时候人们迷恋于建模,并未所有事物建模,这样并不必要。需要给出的忠告是,只在有用时才建立模型。
个人分类: 计算机科学与技术(编程学)|1973 次阅读|0 个评论
[转载]面向对象
coltec11 2014-9-3 04:28
前言:整理这份资料的目的是为了帮助朋友们能够更直观的理解面向对象的编程。让后来者能够少走一些弯路。但其中不免有许多漏洞及错误,也还请前辈提出宝贵的更改意见,毕竟交流会让我们不断的进步。 技术是日新月异的,他不会等待你的成长。技术要拿出来于别人交流,自己学是自己主观意识上的理解,有对有错!交流会让进步变得更快。我认为如果计算机的体系结构不发生革命性的变化,我们现在所应用的程序语言也就百变不离奇踪了!学编程学的是什么?思想!精通一门编程语言(最好是面向对象的语言)后再去搞其他的编程语言,你会发现过程是如此的行云流水!为什么?你已经把编程的思想掌握了,再去学其他的,无非是学习一种新的语法格式了。 我在这里并不是和你讨论怎么去用C++或JAVA,也不是和你讨论怎么去学他们,我要和你讨论的是怎么去理解面向对象。其中主要会涉及到“类、对象、继承、属性、方法、静态、重载、隐藏、重构、声明、定义、初始化、赋值等”其中有许多相关技术我只会一代而过,让你有一种到此一游的意味我就达到目的了,而更详细的技术内幕,就请参考其他相关书籍而深入研究吧!因为我只是在和你探讨如何去更好的理解面向对象! 如何去提高效率?重复使用资源,把别人的东西拿来就用。这是很不错的主意!而对于你来说,最大的资源就是信心以及积极性!好,打起精神来,让我们一同到面向对象的编程中去寻幽访胜吧! 注:文章中所有程序实例我都使用JAVA写的,当然在C++中也就大同小异了了,不同的地方我会指出! 注:文章中的正文文字用黑色,说明文字用蓝色,强调文字用橙色,批改文字用红色! 正文: 1.基本概念: 1.1 类与对象的初探 要我说,无论是面向过程的语言也好,面向对象的语言也罢,我首先要给他讲的都是类和对象!--------“这个世界是由什么组成的?”这个问题如果让不同的人来回答会得到不同的答案。如果是一个化学家,他也许会告诉你“还用问嘛?这个世界是由分子、原子、离子等等的化学物质组成的”。如果是一个画家呢?他也许会告诉你,“这个世界是由不同的颜色所组成的”。……呵呵,众说纷纭吧!但如果让一个分类学家来考虑问题就有趣的多了,他会告诉你“这个世界是由不同类型的物与事所构成的”好!作为面向对象的程序员来说,我们要站在分类学家的角度去考虑问题!是的,这个世界是由动物、植物等组成的。动物又分为单细胞动物、多细胞动物、哺乳动物等等,哺乳动物又分为人、大象、老虎……就这样的分下去了! 现在,站在抽象的角度,我们给“类”下个定义吧!我的意思是,站在抽象的角度,你回答我“什么是人类?”首先让我们来看看人类所具有的一些特征,这个特征包括属性(一些参数,数值)以及方法(一些行为,他能干什么!)。每个人都有身高、体重、年龄、血型等等一些属性。人会劳动、人都会直立行走、人都会用自己的头脑去创造工具等等这些方法!人之所以能区别于其它类型的动物,是因为每个人都具有人这个群体的属性与方法。“人类”只是一个抽象的概念,它仅仅是一个概念,它是不存在的实体!但是所有具备“人类”这个群体的属性与方法的对象都叫人!这个对象“人”是实际存在的实体!每个人都是人这个群体的一个对象。老虎为什么不是人?因为它不具备人这个群体的属性与方法,老虎不会直立行走,不会使用工具等等!所以说老虎不是人! 由此可见-------类描述了一组有相同特性(属性)和相同行为(方法)的对象。在程序中,类实际上就是数据类型!例如:整数,小数等等。整数也有一组特性和行为。面向过程的语言与面相对象的语言的区别就在于,面向过程的语言不允许程序员自己定义数据类型,而只能使用程序中内置的数据类型!而为了模拟真实世界,为了更好的解决问题,往往我们需要创建解决问题所必需的数据类型!面向对象编程为我们提供了解决方案。 1.2 内置数据类型与函数: 计算机程序在存储数据时必须跟踪3个基本属性为: 1. 信息存储在何处; 2. 存储的值是多少; 3. 存储的信息是什么类型的; 让我们来看看编程语言的内置数据类型都有哪些!(呵呵,这个不大好说,因为每门语言都有自己独特的数据类型,但这毕竟是少数,比如在JAVA中有byte类型的数据,而在C++中就没有,希望你能举一反三!)比如整数”int ”,浮点类型的数据”float”!字符串”String”,以及数组还有结构体等等。然而在写程序的时候,根据需要我们会创建一个类型的变量或常量,例如:由于我们需要创建一个整形的变量i为5,我们就可以这样做,int i = 5;而根据需要我很有可能改变i的值,也就是从新给它赋值,比如让它等与6,就可以在所需的地方改成i = 6;由此我们知道,在“值”上可以发生变化的量就叫变量。不会发生变化的量就叫做常量了,在C++中用const关键字来声明,而在JAVA中则使用final关键字来声明。由于不同语言的声明格式不一样,这里就不做一一介绍了,详细的内容清查阅相关书籍! 在这里我们主要讨论一下函数,我们可以把函数想象成一个“实现某种特定功能的黑匣子”-------这个功能是由你来设定的,举个例子来说:现在我问你“2+3等于多少”?我相信你能很快的回答我等于5。让我们来分析分析这句话包含什么信息!首先我要把你的大脑想象成是一个黑匣子,我并不知道也没有必要知道你的大脑是如何工作的(也就是怎么运算的),我关心的只是我传给你的是什么信息?你对信息做了哪些处理? 以及你返回给我的是什么信息?需要提醒你一下的是每个方法都会返回一个信息给调用者的,除了构造函数外(稍候我会作详细的介绍)。我现在需要把自己当作是一名程序员,而你呢?当然就是计算机了!计算机可没有人那么聪明,它只会按事先约好的特定的格式运行,我想让它具有如上所述的功能,我就要先定义这个黑匣子!首先我要告诉这个黑匣子会有两个整数值给你(这就是所谓的参数,是程序员需要给黑匣子的信息),然后就要定义这个黑匣子内部实现这两个整数相加的运算(这就是黑匣子对数据所做的加工,根据需要,你可以做任何的加工。)。最后再标注它返回给我一个同样是整型的数值(这是黑匣子返回给程序员的信息)。一个函数就这样定义完了,让我们来看看书写格式: int addnum(int x,int y){ return x+y; } 具体的含义是这样的: int /*返回值类型*/ addnum /*方法(黑匣子)名称*/ (int x,int y/*传入的参数*/){ return x+y; /*内部是想方法(实现相加运算,)并用return返回给调用者结果*/ } 首先请注意上明的“return”语句!return 关键字的含义是向调用者返回紧跟在它后面的信息!就像上面一样,因为我问你,你才会回答我,如果我不问你,你就不用回答我的!在计算机中也一样,定义好这个函数在哪里调用呢?我只能告诉你,哪里需要就在哪里调用!当然,你可以根据需要去更改参数、返回值以及内部实现,具体到如何定义如何调用你只好去参考相关的资料了!在这里我只是给你一个思想! 有时你会遇到这样的问题,我让你记住,我的年龄是20岁!从字面上理解,你并没有给我返回信息!然而事实上,你确实给我返回了信息,信息的内容是“无信息,也就是无返回值类型void”。具体的程序如下: int myAge = 0; int a=20; void remAge(int a){ myAge=a; } 具体的函数说明如下: int myAge =0; //定义并初始化我的年龄为0; int a=20; /*定义变量a等于20*/ void /*返回值类型为无返回值类型*/ remAge /*函数名称*/(int a /*传入的参数*/){ myAge=a; //内部实现方法,注意,没有return返回!!! } 关于函数的话题还有很多很多,这里就不一一介绍了,我的目的是让你知道函数是怎么一会事儿!为下面的讨论作铺垫! 1.3 指针以及引用: 指针及引用是在C++中有的,JAVA中没有。JAVA中取消了对内存的操作,随之而来的事也取消了操作符重载的操作。不过在稍候我还是会介绍一些操作符重载的功能等。引用主要还是用在函数参数的传递上。所以我在这里就不做过多的介绍了。他们很实用,有兴趣的同学可以参阅C++相关书籍。 1.4 运算符及控制语句: 还是自己看看相关书籍吧,这里就不再熬述了! 2.深入探讨面向对象: 2.1“类型”的内部细节: 有了上面的知识,我们现在就可以深入的挖掘类的内部实现了。所有的知识点我都会围绕着类与对象展开,在此之前,我希望你能够确信对以上所介绍的基本内容已完全掌握了! 是的,面向对象的编程语言最大的特色就是可以编写自己所需的数据类型,以更好的解决问题。我想我必须要帮你搞清楚“类,对象,属性,方法它们之间的关系”!就像我前面所说的,人这个“类”是什么也做不了的,因为“人类”只是一个抽象的概念,它不是实实在在的“东西”,而这个“东西”就是所谓的对象。只有人这个“对象”才能去工作。而类呢?类是对象的描述!对象从类中产生出来!此时,对象具有类所描述的所有的属性以及方法。-------一定要理解这句话!!! 也许你已经有些不知所措了,没关系!好好的回味一下,我再举个例子!例如电视机,电视机都有工作原理图,那么什么叫电视机呢?只要它能够实现工作原理图的所有功能的物体,我们都叫它电视机。你想想是不是这么一回事儿?可是,电视机原理图是不能工作的,也就是这个原理图不能收看节目,只有电视机这个“实体——即所谓的对象”才能收看节目,也就是说,从类生成出对象之后才算得上是真正的有意义!才能开始工作。此时,电视机拥有电视原理图所描述的所有的属性及方法!明白了吧,呵呵! 我先前介绍过,类是属性与方法的集合。而这些属性与方法可以被声明为私有的(private),公共的(public)或是受保护(protected)的,他们描述了对类成员的访问控制。下面我分别做一下介绍: 1. 公共的(public):把变量声明为公共类型的之后,那么就可以通过对象来直接访问,一切都是暴露无遗的!也就是说,你的信用卡密码别人也能够直接得到。 2. 私有的(private):如果把变量声明为私有的情况就好多了,想要得到我的信用卡密码,对象必须要调用专用的方法才能够得到。 3. 受保护的(protected):介绍继承时再讨论。 4. 默认控制访问符(friendly)://JAVA中有而C++中没有。 为了实现数据的封装,提高数据的安全性,我们一般会把类的属性声明为私有的,而把类的方法声明为公共的。这样,对象能够直接调用类中定义的所有方法,当对象想要修改或得到自己的属性的时候就必须要调用以定义好的专用的方法才能够实现。你想想,你会把你的信用卡密码公布出来嘛?呵呵!所以,我们提倡的是:“对象调方法,方法改属性”; 2.2通过实例看内存分配: 说了这么多,让我们来看一个实例吧!比如:现在我们要编写某家公司员工管理系统,你认为最合适的数据类型是什么?我认为是员工个人!但是在面向过程的语言中,这样做是不允许的,因为它只能使用语言中的内部数据类型!而员工不在这个内部数据类型之内!也许有人会说可以用C语言中的struct,好注意!毕竟它是类的基础!如果你以前是一名面C或B的程序员,请你忘掉这些,让我们一起看看如何用类来实现这一切吧! 某家公司的员工是人类的一个特殊群体,它除了具备人类的所有特性与方法外,它还有额外的特性与方法,比如她有她的工资、信用卡密码、作息时间等等,这些特性以及工作内容,工作量等等这些方法。而在计算机中我们该如何定义这个类呢?下面我将写出它的格式,让你看看在计算机中它是张什么样子的! /*在此我需要再次声明的是,我用的是JAVA格式,在语法格式上它与C++大不相同!许多细节以及内部操作都有诸多区别,而在思想上确实大同小异的*/ //employee. java public class employee{ private String name; //员工姓名 private int age; //员工年龄 private char sex; //员工性别 private float emolument; //员工薪水 private boolean lunch; //员工午餐 //……等等 public void heater(){ //这个方法是用来加工员工的午餐 lunch = true; } public void setName(String a){ //这个方法是修改员工的姓名 name= a; } public String getName(){ //这个方法是得到员工的姓名 return name; } //……等等 } 这样我们就定义完了我们所需要的数据类型。现在,让我们来看看它能够干什么以及怎么工作! 我想要做的是,工作室里有一个光杆司令叫“jingwei”,我修改它的名字后对对它进行输出,看看我是怎么做的吧! 注意:请仔细观察对象是如何调用方法的,它使用了“.”操作符!事实上是这样的,对象调用公共的属性或方法时就会使用“.”操作符。 然而在C++中,如果定义一个同类型的指针,该指针调用此对象的方法时,就会使用“-”操作符。更详细的内容清参阅相关书籍了! //workstation.java import java.awt.Graphics; import java.applet.Applet; public class workstation extends Applet{ private employee jingwei ; //对象的声明,此时并不分配内存! public void init(){ jingwei = new employee(); /*此时创建对象会调用构造函数,稍候介绍*/ jingwei.setName(“jw”); //设置我的名字 } public void paint(Graphics g){ g.drawString(my age is +jingwei.getName(),10,10);//显示我的年龄 } } 输出结果是: my name is jw 这串字符串是在输出窗口的x坐标轴为10 px , y坐标轴为10 px的位置。 我现在要做的是,把上面的程序做个大解剖,让你能够看清楚它到底是怎么一回事儿!(我可不时带你去看里面的汇编,呵呵,那个我也不会:) 首先还是来看看我们自定义的数据类型employee,在应用的时候它和int类型的数据没什么两样,一样的需要创建变量(对象),只不过前者是咱自己定义的,而后这是它内置的。Employee这个类中有许多属性,也有许多方法。而此时,我们不能直接用我们所创建出来的对象调用它的属性进行修改。因为它是private受保护类型的!我要想修改我的姓名我就要用对象调用setName()这个方法,而我想得到我的姓名就要调用getName()这个方法。我们完全是按照航线来行走的,这个航线就是“对象调方法,方法改属性” 好的,我真的相信你已经明白了这是怎么一回事儿了!呵呵!仰起航帆,继续前行! 现在让我们一起来看看workstation这个类。这是个主类,和C++中的main()函数的味道差不多。其中,在JAVA中,一个文件只允许有而且必须有一个主类,这个主类用public来声明!他就跟C++中必须要有一个main()函数是一样的。 让我们来看看这个类中的第一条语句!private employee jingwei ;这条语句的作用是声明一个employee的对象jingwei(在C++中就不用声明了)。我想要和你说的是“声明”与“定义”之间的区别。声明只是告诉计算机将要有这样的一个变量(对象),在内存中它并不为这个变量(对象)分配内存!而只有在定义的时候才会给这个变量(对象)分配内存。(需要说明一下的是init()方法是完成初始化操作的,在此处定义对象,为对象分配内存。start()方法用来启动浏览器的主线程,paint()方法来显示Apple的界面。这些是Applet程序所需的,至于Application程序就不需要了,当然了,C++中也不需要他们。关于他们的详细内容清参阅相关书籍) 紧接着就开始定一个对象了,对jingwei这个对象进行操作才会有实际的意义。千万不要有这种想法:“试图对类进行操作!”就像前面我说的,电视机原理不能看电视一样!这是毫无意义的!看这条语句jingwei = new employee();它的意思就是定义一个employee类型的对象jingwei。此时,我想告诉你的是:“jingwei这个对想拥有了些什么”。它拥有了类所描述的所有的属性及方法。下面我一一给你列出来: /*所有的employee对象都拥有这些属性。每创建一个对象就会从新分配一块内存来存放相应对象的这些属性。我的意思是每个对象都有自己“独特”的一份*/ private String name; //员工姓名 private int age; //员工年龄 private char sex; //员工性别 private float emolument; //员工薪水 private boolean lunch; //员工午餐 /*所有的employee对象都拥有这些方法。但在内存中只有一份*/ public void heater(){ //这个方法是用来加工员工的午餐 lunch = true; } public void setName(String a){ //这个方法是修改员工的姓名 name= a; } public String getName(){ //这个方法是得到员工的姓名 return name; } /*但是,实际上在创建jingwei这个对象时计算机只给这个对象的所有的属性分配了内存,而并没有给方法分配内存。方法只有一个,是属于所有的对象的,所以无论创建了多少个对象,计算机只会为一个方法分配一块内存。*/ 我想我还是举个例子吧,不然你非晕倒不可。呵呵! 看我这条语句“private boolean lunch;”公司不管午餐,每个员工都需要带饭。我们现在这样想,公司的空间是所有的内存容量,你的办公桌就是计算机中的内存中的一部分(每个员工都有一份,是在创建对象时分配的)。你把午饭带到了公司,放在了你的办公桌上。“午饭”占据了你的办公桌的一角(占了你自己“对象”的一块内存容量)。这份午饭只属于你自己,同样别人的也只属于她自己!所以每个员工(对象)都需要一快空间(内存)来存放自己的午餐(属性)。在计算机中也是这样的,每创建一个对象,就会在内存中从新分配一块内存来放“午餐——lunch”这个属性(对象所拥有的所有的属性)。 计算机只会为对象的属性分配内存。因为每个对象的都不一样!就像你往公司带的午饭和我往公司带的午饭不一样是一个道理!但方法就不同了。早晨带的饭中午就凉了,你需要用微波炉来加热。微波炉可不用你带,公司就有(只占公司的一块空间),它放在了午餐桌上。你想想,微波炉属于谁的?它属于所有员工的!因为每个员工都可以用它。而不必每个员工都带一份。由此可见,每个员工(对象)都有一份午饭(属性),但所有的员工(对象)只一个微波炉(方法)。所有的员工(对象)都可以通过这个微波炉(方法)来改变自己午餐(属性)的冷热状态。殊途同归!在计算机中也就是这样,方法只有一份,供所有的对象使用!而属性是每个对象一份,因为每个对象的都不一样。别和我说你还不明白,不然我会撞墙的,呵呵:)   2.3深入探讨函数:      2.3.1构造函数、默认构造函数、 缺省构造函数      对于上面的实例,它已经能完成绝大部分工作了,但它还是不完善的,还有许许多多的细节等到我们去完善!也许有的同学已经注意到了,当我创建完“jingwei”这个对象时,这个对象的所有的属性都是空的,也就是说:这个对象的姓名是未定的、年龄是未定的、性别是未定的、薪水是未定的、午餐也是未定的。而我们想把这些属性都添加上去,就还要用对象调用相应的方法,去一个个修改!天啊,这简直是太麻烦了!有没有什么好方法能够在我们创建对象的同时就完成了对属性赋值的操作呢?哦不,应该说是对属性的初始化呢?当然没问题了,这就需要所谓的构造函数!   构造函数是类中最特殊的函数,它与析构函数的功能正好相反!   从特征上来说:1.它是编程语言中唯一没有返回值类型的函数。   2.它的名称与类的名称必须要完全相同。   3.它必须被声明为公共(public)的类型   4,可以对构造函数进行重载。   5.它在创建对象时自动被调用。   从功能上来说:1.它是对类中的属性进行初始化。     其实,对于上面的程序来说我们没有自己定义构造函数。但是,在这种情况下,系统会自动为我们定义一个“默认构造函数”。他会把数值变量自动赋值为0,把布尔行变量赋值为false等等(但在C++中,默认构造函数不初始化其成员)。如果程序员定义了构造函数,那么系统就不会再为你的程序添加一个缺默认造函数了。(在这里,我们提倡的是自己定义构造函数,而不是用系统的默认构造函数)   还是看个实例吧!这样比较清楚一些!   //employee.java      public class employee{      private String name; //员工姓名      private int age; //员工年龄      private char sex; //员工性别      private float emolument; //员工薪水      private boolean lunch; //员工午餐      //……等等      public employee(){ //这个就是“默认”构造函数      name = “jw”; //设置员工姓名      age = 20; //设置员工年龄      sex = “M”; //设置员工性别      emolument = 100; //设置员工薪水      lunch = false; //设置员工午餐      }      public void heater(){ //这个方法是用来加工员工的午餐      lunch = true;      }      //……等等      };   这样,在我们创建“jingwei”这个对象的同时,它的所有的属性也被初始化了!显然,这大大的提高了工作效率,但是,它还是不符合要求。想想看,如果我们现在创建这个类型的第二个对象的时候会发生什么事情?告诉你,除了对象的“名”(这个名称不在是对象属性中的名称,而是对象本身的名称)不一样外,其所有的“属性值”都一样!比如:现在我们创建第二个对象flashmagic,然而我会发现这个对象的所有的属性和jingwei这个对象的所有的属性完全相同。而我们只能在用对象的方法去改变着写属性了!很显然,这种方法不大好!我们需要一种方法在创建对象的时候为对象的属性赋予“我们想要的值”。   相信你也看到了,默认构造函数就显得无能为力了。我们需要的是带参数的构造函数,在创建对象时,我们把参数传给构造函数,这样就能完成了上述的功能!口说无凭,还是来看个实例吧:   //employee.java      public class employee{      private String name; //员工姓名      private int age; //员工年龄      private char sex; //员工性别      private float emolument; //员工薪水      private boolean lunch; //员工午餐      //……等等      public employee(String n,int a,char s,float e,boolean l){ //看这个构造函数      name = n; //设置员工姓名      age = a; //设置员工年龄      sex = s; //设置员工性别      emolument = e; //设置员工薪水      lunch =l; //设置员工午餐      }      public void heater(){ //这个方法是用来加工员工的午餐      lunch = true;      }      //……等等      };   这样一来,在创建对象的同时我们就可以给他赋予我们想要的值,很显然,这可就方便多了。哦,对了!还没有告诉你怎么创建呢!哈哈,往前翻几页你会看到这句话:   jingwei = new employee();这是创建一个对象,而我们把它改成   jingwei = new employee(jingwei,20,   2.3.2重载构造函数:   我还是先把概念给你吧,让你有个认识,随后我们在进行论述。   在JAVA中:   1. 函数重载是一个类中声明了多个同名的方法,但有不同的参数个数和参数类型。   2. 函数重构是指在子类中声明与父类同名的方法,从而覆盖了父类的方法。重构解决了子类与父类的差异问题。(在讨论到继承时我会详细说明)   在C++中:   1. 数重载的概念一样。   2. 重构的概念可就不一样了,C++中功能更为庞大的虚函数。更详细内容这里就不错过多介绍了!   其实关于重载的概念你并不陌生,在编程中相信你也接触过。呵呵!让我们来举个操作符重载的例子你就会明白了,(JAVA中不支持这个功能)我们定义三个整数变量:   int i1=2, i2=3,i3=0;      i3 = i1 + i2;      此时i3=5;加号实现了两个数相加的运算功能。然而我们现在要定义三个字符串变量:      String str1=”jing”, str2=”wei”,str3=””;      str3 = str1 + str2;   此时str3 = “jingwei”;加号实现了两个字符串相加的运算功能。同样是加号,既可以把两个整型的变量加在一起,也可以把两个字符串类型的变量加在一起。同一个操作符实现了不同的功能------这就是所谓的操作符重载(嘿嘿,我说你一定见过吧:)!不就好像是汉语中的一词多意一样!我需要说明一下的是,C++中的操作符重载可没有这么简单。比如,我们可以对两个自定义类型的对象进行相加的运算,进行赋值的运算。这样书写简洁明了,而且非常实用。当然,关于操作符重载的话题太多了,有兴趣再看看书吧!   我们把操作符的话题在转到函数上来,我们一直强调的是“对象调方法”------对象其实调的是方法的“名称”。而我们现在要对方法进想重载,也就是定义多个相同名称的函数,这样计算机在调用的时候不会混淆嘛?我想应该不会的,呵呵,因为仅仅是函数名称相同,而我们在调用函数时会把参数传递给他的。既是没有参数也是一种参数传递参数的信息(信息为无参数)!然而由于参数类型、参数数量、返回值类型不同我们就可以对相同名称的函数进行区分了!目的只有一个,用简便的方法实现更多的功能。还是举个例子吧,重载构造函数!   public class employee{      public employee(String n,int a,char s,float e,boolean l){ //看这个构造函数      name = n; //设置员工姓名      age = a; //设置员工年龄      sex = s; //设置员工性别      emolument = e; //设置员工薪水      lunch =l; //设置员工午餐      }      public employee(){ //请注意这个函数没有参数      name = “jw”;      age = 20;      sex = ’W’;      emolument = 99;      lunch = true      }      //……等等      };   看,在一个类中有两个名称相同的函数,可我们在使用的时候系统如何知道我们调用的是那个版本的函数呢?呵呵,我刚刚说过了,可以通过函数的参数类型、参数数量、返回值类型来确定。现在我们接着试验,我们创建两个对象其中的一个调用带参数的构造函数,第二个对象调用缺省值的构造函数。我们来看看结果:   jingwei = new employee(jingwei,20,'M',100,false);/*创建这个对象的时候调用的是带参数的构造函数*/      flashmagic = new employee();//创建这个对象是调用的是却省值的构造函数      而得到的结果呢?让我们一起来看一看!      Jingwei这个对象中: flashmagic这个对象中:   name jingwei name jw   age 20 age 20      sex M sex W      emolument 100 emolument 99      lunch false lunch true   看,虽然是两个名称完全相同的函数,但完成了不同的工作内容。呵呵!关于函数重载我们就料到这里吧,我相信你已经有个大印象了,而更详细的内容仍需要你的努力!   重载普通的函数与重载构造函数大同小异,不过他多了一个this指针!this一般是对当前对象的引用。这么说吧,如果涉及到两个以上的对象时就会使用this指针。每个成员函数都有一个this指针,它是一个隐藏的参数,this指针只向调用它的对象!我说过方法只有一份,而对象都有自己的属性,当对象调用方法来先是属性的时候,他怎么来判断调用的时不是自己的属性呢?这就需要this指针来大显神威了。   关于拷贝构造函数、内联函数、虚函数、模版等欧就不做过多的讨论了,因为JAVA中好像没有这些了。不过我需要提醒你一下的是,在C++中,类内定义的函数自动转换为内联函数,而这好像与我前面提到的思想有冲突。因为内联函数的目的是减少函数调用的开销!呵呵!我也没绕出来呢!还请哪为大虾指点一二!谢!   2.3.3 初始化与赋值   这里我却要提醒你一下的是,初始化与赋值是完全不同的两个概念。创建一个类的时候会调用这个类的构造函数对对象的属性进行初始化。而如果以后再把这个对象赋给其他同类型的对象时可就没那么简单了。在JAVA中直接赋值就行了,因为JAVA中取消了指针,不存在指针的深拷贝与前拷贝问题。而在C++中就需要拷贝构造函数以及操作符重载了。因为JAVA中不牵扯这些东西,所以偶就不做过多介绍了。详情请参阅相关书籍吧!   2.3.4析构函数:   JAVA中不再支持指针了,所以你感觉不到它的重要性,因为系统会自动为你释放内存。而在C++中一切都是手动的。在构造函数中new了一个指针,在析构函数中就要delete这个指针。   2.3.5静态:   现在我们再来看一看“静态”是咋一回事儿!   把一个变量或函数声明为静态的需要“static”这个关键字。声明静态的目的是“为某个类的所有对象的某个属性或方法分配单一的存储空间”。静态的数据是属于类的,不属于任何的对象。静态的数据在声明的时候系统就为他分配了内存空间,而不用等到创建对象时。举个例子来帮你更好的理解它吧。   还是接着上面的例子。还记得刚刚我说过的员工能用微波炉热饭的事情吧。现在我们要找一个手套,毕竟想把热好的饭从微波炉里拿出来直接下手是不行的。我把手套定义成一个布尔型的变量,它有干净和脏两种状态。想想看手套是属于谁的?所有对象?不对!因为只有方法才能属于所有的对象。它是属于类的,它像微波炉那个方法一样,在内存中只有一份,所有的对象通过方法都能够修改它。而下一次修改是基于上一次修改的基础之上的!我的意思是:一个员工把手套弄脏了,下一个员工在使用的时候它还是脏的。而这个员工把手套洗干净之后,别人再用的时候它就是干净的了!就这么点事儿,明白了吧!   关于静态函数我想就没什么可多说的了。给我的感觉就是,它也是属于类的,在定义的时候就分配的内存。调用是可以使用类名直接调用。其他的和普通成员函数没什么不同的了不过这里需要说明的一点是:在JAVA中,静态的成员函数只能修改静态的属性,而静态的属性可以被所有的成员函数修改。不过在C++中就没这么多事儿了!   2.4继承   继承很好理解,它的最大好处就是“代码重用”,大大提高了工作效率。举个例子你就明白了。世界上先有的黑白电视机,它有自己的工作原理。然而人们在他的基础之上开发出了彩色电视机。彩色电视机继承了黑白电视机的所有的特性与方法!因为它既能显示彩色图像也能显示黑白图像。然而它与黑白电视机又有许多区别,在工作原理上。彩色电视及多了矩阵色电路,把彩色信号分离出三种颜色(RGB),他就能显示彩色的图像了。而黑白电视机没有这块电路,即使它收到了彩色信号也显示不了彩色图像。彩色电视机是从黑白电视机中派生出来的。所以,黑白电视机是父类,彩色电视既是子类,彩色电视继承了黑白电视机所有的特性与方法。看看再计算机中它是什么样子的吧:   //BWtv.java 父类的定义      public class BWtv{      private int a;      public BWtv(){      a=1;      }   public changeBWtv(int i){      a=i;      }      }      //Ctv.java 子类的定义      class Ctv exntends BWtv{ //注意关键字“extends”      private int b;          public Ctv(){        b=2;      }      public changetCv(int x){      b = x;      }      }   有了上面的定义,我们来看看他们都有什么数据。   BWtv的数据包括     Ctv的数据包括      private int a     private int a                 private int b      public changeBWtv(); public changeBWtv()      public changeCtv();   你看,子类拥有父类的所有的方法及属性。注意关键字”extends”,它的意思是继承。在C++中使用的是“:”操作符。意思是一样的。但是这里有许多问题,首先是访问权限的问题,子类的对象拥有父类的所有的属性和方法这句话。对嘛?肯定是对的!(不过JAVA的书中可不是这么说的,他说只继承非private类型的属性及方法,我觉得它这句话有错误!)可是,子类的对象不能直接访问父类的私有属性或方法,它只能通过父类的公有成员函数来访问。而此时,如果你修改了父类的属性的值。那就真的修改了。我的意思是:父类的私有属性的值会随着子类对象调用父类的公有方法进行对相应属性的修改而发生变化!(这里面存在一个域的问题,所有的修改都是在子类中进行的,修改的是子类继承的父类的属性(在子类这个域中,此时父类以拷贝到子类中了。)。而程序中定义的父类的属性不会发生任何变化(在父类的域中),)   其次是构造函数,在创建一个子类对象时首先要调用的是父类的构造函数,然后再调用子类的构造函数,毕竟,子类的构造函数不包括父类的属性的初始化功能!(从这一点来说我的观点又是正确的“子类的对象拥有父类的所有的属性和方法”)当然了,析构函数的调用顺序正好相反!   现在让我们来谈谈protected这个关键字吧,它的意思是:对对象来说,声明为protected的变量是私有的,而对子类父类来说,声明为protected的变量是公共的。   现在又出现了这样的一个问题,如果我们在子类中也定义了一个int 类型的变量a,那我们在创建子类的对象的时候调用的是子类定义的还是父类定义的呢?这就涉及到数据的隐藏的问题了,我可以告诉你肯定是调用的子类的变量a。因为,子类把父类的这个同名变量给隐藏了。而如果是方法呢?这就涉及到重构的问题了,在上面我提到过“函数重构是指在子类中声明与父类同名的方法,从而覆盖了父类的方法。重构解决了子类与父类的差异问题。”这里必须要声明一下的是,在JAVA中,子类出现了对父类属性的隐藏和父类方法的覆盖后,在子类中,子类对象仅能调用子类本身的属性和方法。要调用父类的属性和方法必须要实用super这个关键子。而在C++中就不这样了。因为它有虚函数。   虚拟函数在C++中非常好玩的事。我们可以把需要改写的函数声明为虚函数,用virtual这个关键字来声明。这样。假如如果我们CwinApp这么一个基类,它里面定义了一个成员(虚)函数为InitInstance()和另一个为(虚)函数InitApplication()。如果我从CWinApp派生一个子类为CMyWinApp并修改了InitInstance()这个成员函数。我们并没有修改InitApplication()这个成员函数。现在我们创建CMyWinApp这个类的函数theApp,我们并创建一个指针*pApp指向这个对象theApp。此时:   pApp-InitInstance() //指针调用的是子类CMyWinApp的虚方法   pApp-InitApplication() //指针调用的时父类CwinApp的虚方法     因为子类并没有修改父类的方法,所以调用的是父类的虚方法。这就牵扯到虚你表的问题。碍与本篇文章的定位,这里就不讨论了!     关于父类与子类的对象的类型转换问题是这样的,子类对象转换为父类对象时,不会出现错误。因为子类包含父类的所有的属性及方法,而父类向子类转换时就难说了,呵呵。这还会牵扯到虚拟表的问题,也不讨论了!   JAVA中不再支持多重继承,也就是一个类从两个以上的类中继承而来,但它却多了接口的概念“interface”。这里就不做过多介绍了!   关于抽象基类也没什么难的!他的一个大概念就是:做为许多类的父类,不定义对象,只做派生用! 我能做得也只有这些了,如果你能明白以上的六七成,那就是对我最大的回报了,呵呵!就像刚刚开始我说的,我只是给你一个大概的思想,至于内部的实现细节,仍需要你的继续努力。关于编程语言的内容还有许多许多,实属小生个人能力有限而不能全盘照顾到。不过作为一个初学者的你来说,这些东西都是基本的。需要我提醒你一点的是,不要指望在第一、二遍的时候看懂什么!加油:)   2004.4.29 韩景维
864 次阅读|0 个评论
简单理解面向对象设计模式
taiyangqi 2014-8-19 17:41
模式类别 模式名称 模式来源(解决的问题) 模型结构 具体应用实例 模式说明 创建型模型( Creational Pattern ) 关注对象的创建过程,对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离,对用户隐藏了类的实例创建细节。 抽象工厂模式( Abstract Factory Pattern ) 产品等级结构:电视机是抽象类、海尔电视机是其子类 产品族:比如海尔公司生产的一系列电器 简单工厂模式中工厂类职责过重,工厂方法模式引入工厂等级结构解决此问题,但工厂不单单生产单个产品 抽象工厂 具体工厂 抽象产品 具体产品 某公司要开发一套界面皮肤库, spring 风格的将提供浅绿色的按钮、绿色边框的文本框和绿色的组合框; Summer 风格将提供浅蓝色。。。(缺陷:设计之初没有将 radiobutton 考虑进来,以后添加将会很麻烦,违背开闭原则) 提供一个创建一系列相关或相互依赖对象的接口而无需指定他们具体的类 建造者模式( BuilderPattern ) 事物由复杂对象组成,例如:汽车包括车轮、方向盘、发动机等多种部件,考虑如何将这些部件组装成一辆汽车 抽象建造者 具体建造者 产品 指挥者 游戏公司开发的人物:游戏中的角色是个复杂对象,含性别、面容等,还会随等级升高变化,可以分为天使、魔鬼等,他们都拥有面容、性别、服装等,创建过程大同小异,因此可以逐步创建其组成部分再将各组成部分分装成一个完整的角色。 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 原型模式( Prototype Pattern ) 孙悟空拔毛变小猴(克隆) 抽象原型类 具体原型类 客户类 员工在制作周报的过程中发现很多重复的地方,希望用快速的方式制作相同或相似的周报(涉及浅克隆和深克隆) 使用原型实例指定待创建对象的类型并且通过复制这个原型来创建新的对象 单例模式( singleton pattern ) Windows 资源管理器,只能有一个对象,如果出现多个窗口,第一浪费资源,第二如果窗口显示内容不同,说明系统存在不同的状态 只有一个单例类 服务器负载均衡软件的开发,由于集群中的服务器需要动态删减,且客户端请求需要统一分发,因此需要确保负载均衡器的唯一性,只能有一个负载均衡器来负责服务器的管理和请求的分发,否则会带来服务器状态的不一致性以及请求分配冲突的问题。 确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例 结构型模式( Structural Pattern ) 关注如何将现有的类或对象组织在一起形成更加强大的结构 适配器模式( Adapter Pattern ) 我国生活用电是 220V ,而笔记本电脑、手机等的工作电压没那么高,需要充电器或变压器来调配电压 目标抽象类 适配器类 适配者类 教务系统中,拥有二分法和快速排序等方法类,但已找不到源代码,并且也已经针对这些代码进行了接口编程,需要设计模式,在不修改以上两个类的源代码的前提下,将这两个类的方法配置到成绩操作接口。 将一个类的接口转换成客户希望的另一个接口,适配器模式让那些接口不兼容的类可以一起工作 桥接模式( Bridge Pattern ) 毛笔和蜡笔,分大中小和 12 种颜色,蜡笔得要 36 支,毛笔只要三支, 12 个涂料,如果要在加不同颜色和型号,蜡笔要成倍增加,毛笔则不用(蜡笔中颜色和型号的耦合性比较高、毛笔中颜色和型号的耦合性比较低) 抽象类 扩充抽象类 实现类接口 具体实现类 某公司开发的图片浏览器,要求能浏览 jpg,png 等多种格式文件,同时还要求能在 Windows 、 Linux 等操作系统上实现 将抽象部分与实现部分解耦,使得两者都能够独立变化 组合模式( Composite pattern ) 操作系统的目录结构、菜单结构和公司组织结构等 抽象构建 叶子构建 容器构建 开发杀毒软件,既可对文件夹杀毒也可对图像、文本等杀毒 组合多个对象形成树形结构以表示具体部分 - 整体关系的层次结构。组合模式让客户端可以统一对待当对象和组合对象 外观模式( Faade Pattern ) 刘备和曹操想喝茶,如果自己泡,两个人分别要买茶叶、茶具、茶叶等、复杂。如果同到茶馆,由服务员泡茶,不管多少人,都是一套茶具、茶叶,只是多了个服务员 外观角色 子系统角色 开发一个科应用与多软件的文件加密模块,读取源文件、加密、保存加密后文件,三个操作相互独立,可重用 为了系统中的一组接口提供一个统一的入口,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 享元模式 软件系统创建相同或相似的大量的对象,占用大量内存。考虑使用共享技术实现相同或相似对象的重用,在逻辑上每个事物都有一个对象与之对应,而在物理上却是共享一个享元对象,这个对象可以出现在不同地方,但相同事物指向同一实例。 抽象享元类 具体享元类 非共享具体享元类 享元工厂类 开发围棋游戏,围棋分为黑白棋,旗子众多,没必要每个棋子拥有一个物理对象,它唯一不同的就是在棋盘上的位置,只要在记录棋盘的坐标就可以完美地解决这个问题 利用共享的技术有效地支持大量细粒度对象的复用 代理模式( Proxy Pattern ) 代购 抽象主题角色 代理主题角色 (3) 真实主题角色 商务信息查询系统 (1) 进行商务信息查询之前用户需要身份验证,合法用户才能查询 (2) 商务查询时系统需要记录查询日志,以便根据查询次数收取查询费用 给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问 装饰模式( Decorator Pattern ) 对房子的装修并没有改变房屋居住的本质,但它可以让房子变得更漂亮、更温馨,软件设计中,可以对对象进行功能扩展,获得更符合用户需求的对象 抽象构建 具体构建 抽象装饰类 具体装饰类 开发图形界面构建库,基本构建如窗体、文本框、列表框的等,用户需要定制特殊效果,如带滚动条的窗体、带黑色边框的文本框、既带黑色边框又带滚动条的列表框 动态地给一个对象增加一些额外职责,就扩展功能而言,装饰模式比子类更加灵活 行为模式( Behavior pattern ) 关注系统中对象的交互,研究系统在运行时对象之间的相互通信和协作,进一步明确对象的职责 职责链模式( Chain of Responsibility Pattern ) 大学生奖学金申请,需要通过辅导员、系主任、院长、校长的审批,学生直接面对的只有辅导员,其他的都没有直接面对,申请要求只要条件符合就是一直往下传递的 抽象处理者 具体处理者 供应链管理系统中的采购审批子系统,主任能审批 5 万以下单、经理 5-10 万、董事长 1-50 万等,要加新角色,只要新增一个具体处理类 避免将一个请求发送者与接受者耦合在一起,让多个对象都有机会处理请求,将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到一个对象能够处理为止 命令模式( Command pattern ) 人们通过使用开关来控制一些电器的开关,购买时,用户不知这些开关将用于控制什么,他们之间没有直接关系 抽象命令类 具体命令类 调用者 接收者 系统提供一系列功能键,用户可以自定义功能键的功能 将一个请求封装为一个对象、从而让你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作 解释器模式( Interpreter Pattern ) 编程语言中就有典型的解释器,输入一个句子,根据文法规则实现相应的功能 抽象表达式 终结符表达式 非终结符表达式 环境类 机器人控制程序,用英文表达式命令机器人运行 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子 迭代器模式( iterator Pattern ) 两种方式控制电视机 (1) 电视机主板上的按钮 (2) 电视遥控器 电视机是一个节目类,以上两种方式对它进行操作 抽象迭代器 具体迭代器 抽象聚合类 具体聚合类 系统中的商品数据和销售数据经常被遍历查询,可以设计一个数据集合类,将存储商品和客户等数据的类作为其子类 提供一种方法顺序访问一个聚合对象中的各个元素,且不暴露该对象的内部表示 中介者模式( Mediator Pattern ) QQ 聊天中存在两种聊天模式,直接聊天和群聊,发送同一份信息或文件,直聊需要一一天剑好友,对象变多,群聊不用,对象较少 抽象中介者 具体中介者 抽象同事类 具体同事类 一个信息界面中,一条信息既在下列列表中,又在列表中显示,删除和添加一条信息都要交互多个控件 定义一个对象来封装一系列对象的交互。中介者模式使各对象之间不需要显式地相互引用,从而使其耦合松散,而且让你可以独立地改变他们之间的交互 备忘录模式( Memento pattern ) 不小心删除一些图文,需要后悔药来返回 原发器 备忘录 负责人 开发象棋等游戏时,可以考虑有悔棋这一按钮 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以在以后将对象恢复到原先保存的状态 观察者模式( Observer Pattern ) 红灯停、绿灯行。交通信号灯是司机的观察目标,司机是观察者,随着信号灯的变化,司机的行为也随之变化,一盏信号灯可以指挥多辆汽车。 目标 具体目标 观察者 具体观察者 联机游戏中,同一战队的成员,当一个成员遭受攻击时,将给所有同伴发求救,盟友将作出相应反应 ( MVC 模式是一种典型的观察者模式) 定义对象之间的一种一对多依赖关系,使得当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新 状态模式( State Pattern ) 水在一定条件下结成冰,化成水蒸气,但它们又是相互**的 环境类 抽象状态类 具体状态类 银行账户管理器 账户余额和权限的关系,大于 0 ,正常,可取可存,大于 -2000 ,小于 0 ,透资,可取可存,算利息,小于 -2000 ,受限,可存不可取,算利息 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎改变了它的类 策略模式( Strategy pattern ) 旅行过程中的交通工具选择,飞机、火车、自驾等 环境类 抽象策略类 具体策略类 打折系统,学生 8 折,小孩 10 元, vip 半价和积分,要引入新的打折对象,只要增加新的折扣类即可 定义一系列算法,将每一个算法封装起来,并让他们相互替换,策略模式让算法独立于使用它的客户变化 模板方法( Template Method Pattern ) 很多事情都包含几个实现步骤,如请客吃饭,首先是下订单、吃东西、买单,下单和买单大同小异,吃东西差别巨大,相同方法反复使用,不同的方法区别对待 抽象类 具体子类 利息计算器 登陆账号,错误则提醒错误 正确,根据不同身份执行不同的事务,调用不同的利息计算公式 显示利息 定义一个操作中算法的框架,而将一些步骤延迟到子类中,模板方法模式使得子类不改变一个算法的结构即可重定义该算法的某些特定步骤。 访问者模式( Visitor pattern ) 药单开好后,划价人员拿到处方之后根据药品名称和数量计算总价,药房工作人员根据药品名称和数量准备药品 抽象访问者 具体访问者 抽象元素 具体元素 对象结构 员工信息管理子系统,正式员工、临时工,工作时间、工资,人力资源部关注工作时间,财务部关注工资 两者工作内容和标准不同 表示一个作用于某对象结构中的各个元素的操作,访问者模式让你可以再不改变各元素的类的前提下定义作用于这些元素的新操作 阅读完《设计模式:可复用面向 软件的基础》一书后,23种设计模式让人眼前一亮,模式来源,简介,说明,代码实现,适用的环境等。都让我很受益,完全理解不太可能,尽我最大努力做一份笔记。作为一名GIS 学生,最大的愿望还是能将面向设计模式的思想用到GIS 软件 设计中,曾经也算做过一些GIS二次开发,慢慢整理内容,阐述GIS二次开发涉及到的面向对象设计模式思想。
个人分类: 读书笔记|2535 次阅读|0 个评论
关于软件编程方法的联想
ws0110 2012-10-31 23:15
面向过程的方法:如果想做一把吉他,你得先把它分解成琴头、琴脖子、琴身、琴弦等。琴身又可以进一步分解成面板、背板、侧板,这样自上而下逐步降低其复杂度 ,然后选用相应的材料分别制作完成,这个过程可比作模块化编程,制作吉他是个主函数,制作琴身是个子函数(模块),制作面板是个子函数的子函数(子模块)。 面向对象的方法:吉他做好后,暴露在外面的是琴弦,其他的属性都被封装了,吉他成为一个对象。如果想演奏,那还得有个吉他手,这时候吉他是个对象,吉他手是另外一个对象。吉他手通过调用弹、 拨、点、勾等方法,向吉他发出消息,吉他响应消息,发 出优美的旋律。 面向接口的方法:吉他手一旦学会了一把吉他的弹奏,当然不希望换把吉他就不会弹了。那就得给吉他定一个标准,比如说,凡是可以通过弹、 拨、点、勾等方法进行演奏的乐器那就叫做吉他。这样,吉他手和吉他是上下层的关系,不用因为换一把吉他,就得换吉他手。 面向组件的方法:如果要搞个乐队,光有吉他和吉他手是不够的,还得有架子鼓、鼓手、电子琴、键盘手等这些对象。一般来说吉他是吉他手自己携带的。这时候可以再做一层封装,就是把吉他对象和吉他手对象封装成一个“乐队组件”,把电子琴和键盘手封装成另外一个乐队组件。因为乐队组件是具有 相对独立演奏功能、可独立演奏的实体。组装个乐队就很简单了 。 面向代理的方法:乐队得挣钱吧,如果乐队很有名,自己出面去联系演出,掉面子,自己等人上门找,公布联系方式又怕被骚扰,这怎么办?开发个网站怎么样?网站没有独立心智,只能被动的等别人找到你,而且不会讨价还价。那就找个经纪人吧。经纪人得具有以下几个最基本的特征,反应性,得了解市场的行情、热点城市、哪里准备搞演唱会,然后作出反应;主动性,经纪人得主动去联系演出,把乐队演出排满了,自己也才有钱挣;自治性,一场演出多少钱,经纪人可以全权代表乐队去谈,在底线的基础上得到尽量多的报酬。 面向方面的方法: 如果每个乐队和明星都找经纪人,也有些麻烦,一个人养一个经纪人可能成本较高,经纪人不干了得重新找,经纪人请病假或事假还没了生意。要统一解决经纪问题,那就干脆签约经纪公司吧。这种统一解决不同对象或组件的共性问题的方法,就叫面向方面的编程。 面向服务的方法: 除了公司提供经纪服务,明星们还可能希望享受到其他服务,比如说他还希望有人打扫卫生、做饭、伺候坐月子、教小孩学习等,那他可以去找各种各样保姆和家教,也可以统一找家政公司服务。这样根据需要把不同的服务整合起来,你就可以过上明星般的醉生梦死的生活。 网格计算:这好比要搞一台央视春晚(聚合分散的资源满足大型应用),春晚太复杂了,不是一两个人导演、一两个明星、一两个乐队就能搞定(对任何单一的超级计算机来说仍然大得难以解决的问题),必须将其分解成歌舞类、语言类、戏曲曲艺类等一个个节目(子任务),然后再找一些春节期间无档期的明星大腕(空闲的计算资源),让他们帮忙分别创作、排练(分布式计算),最后把一个个节目整合串在一起才能成为春晚(犹如巨大的虚拟计算系统)。其中任何一个节目搞砸了,都会影响后续节目的进行和整台晚会的效果(网格的某个节点如果失效,可能会影响到其他节点和最终的计算结果),所以唱歌的一般都假唱,语言类的排练能把你累死,难怪宋丹丹、范伟吃不消,死也不再上了。 云计算:这就好比有一个 KTV (集中资源满足大众应用),你不用管音响效果,不用买功放、电视、麦克风(基础设施既是服务),不用找乐队伴奏(平台既是服务),不用怕跟不上节奏,不用记歌词(软件既是服务)。唱戏,唱红歌也好,唱 RAP ,唱摇滚也罢,不管你是唱美声、唱通俗还是唱民族,想唱什么就唱什么(一切皆服务)。
个人分类: 随心随性|2647 次阅读|0 个评论
今日灵感:行为、结果与对象的关系
热度 4 Babituo 2011-4-6 09:16
1.行为依赖已有的结果,导致未来的结果。 2.行为受已有的结果推动,受未来的结果牵引。 3.自主行为只受自我设定的未来结果的牵引。 4.被动行为受其他行为输出结果的推动,或其他行为所需结果的牵引。 5.推动和牵引是两种不同的驱动机制。 6.相关连的多个行为与结果构成一个关系网络。 7.相互耦合紧密的行为-结果关系网可定义为一个对象。 8.可从不同的角度对有交集的行为结果关系网定义不同的对象。 9.行为关系网就是本体,对象是比行为-结果关系网更高层的抽象。 10.定义了对象之后: 10.1被对象定义所包含的行为-结果关系网,就是对象的内部结构。 10.2没有被对象定义包含的行为-结果关系网,就是对象的外部环境。 10.3对象的外部环境和内部结构,依然可以再定义对象。 10.4当全部的行为-结果关系网都被定义为不同的对象时,行为-结果关系网显现为对象关系网。 10.5对象的内部结构上与外部环境交界处的行为,就是对象的方法。 10.6对象的内部结构上与外部环境交界处的结果,就是对象的属性。 10.7一组互不冲突的对象关系网定义形成一个系统的对象范式,代表一种对系统的认识角度。 10.8不同角度的对象关系网定义互不相干,底层对应同一个行为-结果关系网的运行。 10.9在对象关系网层面,依然可见推动和牵引两种驱动机制。 10.10于是,对象的外显行为-结果(方法和属性)都是对内部对象关系运行过程的封装。 对象可以选择受哪个结果的牵引或哪个结果的推动,这便是自主性的由来。 对象的自主性,只是从对象内部的组成对象看自身而来的。 内部组成对象是看不到所组成的上层对象的外部环境的。 对象选择受哪个结果的牵引或推动的行为,就是对象自身的一种搜索与定位的行为,即:体旋行为。 当对象之间建立推动或牵引关系之后, 从同层对象看来,维持关系运转的行为是输入输出的新陈代谢行为,即线旋行为。 从上层对象看来,正是这一组内部的运转关系的稳定进行,维持了对象的外部团结与凝聚的形象,对上层对象而言,这组行为就是面旋行为。 这便是三旋动态对象架构的实质。 面向对象思想和三旋理论思想对接完毕。 一组对象关系网总是可以定义为更高层的一个对象。 高层对象的规模越来越大,以致无法想象成是一个对象,只好想象是一组开放的对象关系网络。 于是,多对象参与的一组相关的行为,被定义为一个服务。 对象关系比较松散,可动态组合,被定义为一个团队。 于是,出现相对松散的团队-服务的观点,这便是SOA架构的实质。 团队-服务关系网,依然以行为-结果关系网为本体,是对象关系网基础之上的又一层抽象。 团队-服务关系网,仍然按推动-牵引机制运行。 团队-服务关系网,按三旋动态分工组合,是实现自组织架构的必经之路,并是捷径。
个人分类: 信息探索|4162 次阅读|9 个评论
哲学世界的对象关系图-面向对象的知识表达范例
热度 3 Babituo 2011-3-10 08:51
看图说话: 1.哲学世界包含一个现实世界和一个虚拟世界; 1.1.现实世界包含一个物质世界、一个心智世界和一个互动世界; 1.1.1物质世界存在物与物之间的互动操作,叫物物互动; 1.1.2心智世界存在心与心之间的互动操作,叫心心互动; 1.1.3物质世界和心智世界之间存在物与心的互动操作,叫心物互动; 1.1.4物物互动、心物互动和心心互动共同组成互动世界。 1.2.虚拟世界至少包含一个语义逻辑世界; 1.3物质世界遵从语义逻辑所规定的客观规律; 1.4心智世界表达和演绎语义逻辑; 1.5互动世界实现和呈现语义逻辑。 一句话概述:现实世界的物质与心智的各自间的互动,无非是遵从、表达或实现虚拟世界的语义逻辑。 模型完毕。 模型讨论: 互动世界就是信息世界。 语义逻辑世界,也可称逻辑世界、知识世界、语义世界。 关于现实世界和虚拟世界的界定 用例子说话: 比如迷信的人,看到有人得了怪病,就会说,是“鬼”造成的。 在迷信的人看来:“鬼”是一种实际的存在,他们认为,这个世界上确确实实是有“鬼”这种事物,并且还可以装弄出确实“有鬼”的效果出来。不可否认,在装神弄鬼的人当中,并不是所有的人都是有预谋的骗子,而是他们确实相信有鬼的存在。 在讲科学的人看来:“鬼”只是迷信者虚拟构造的一种“事物”,这种事物在现实世界是不存在的。迷信者看到的“有鬼”的现象,只是自然界中的一些很少见的现象,人们对这些现象背后的客观规律认识还不够清晰或不够普及。这些现象,一定是自然法则结合适当的现实自然条件而造成的。 客观来说,相信科学的人和迷信的人,都是在用一种虚构的“事物”,来解释实际的现象。相信科学的人只是用“客观法则”取代了迷信者的“鬼”。“客观法则”其实和“鬼”在这里在“虚拟”的意义上来说,是一样的,是没有实际的存在事物来对应的。 尽管我们可以从现象上合理地推断“鬼”或“客观法则”是存在的,但这种“存在”,不仅仅是一种无形的存在,还是一种完全就是虚构的存在,没有任何物质和能量载体支撑的存在。尽管我们可以用文字、现象来表述它们,但我们只是表述了它们而已,它们本身依然还是“被虚构”的,与那些“真实具体”的事物比较起来,差异还是明显的——真实具体的事物,至少是能产生相互作用的、有物质和能量载体的事物。 我们有时说“心智(意识)”是无形的,只是从通常的观测手段上来说的,借助更先进的仪器设备,我们可以像显示磁场一样来显示意识的形。这种“意识”的无形存在,与那种完全是“被虚构客观存在”的关键不同之处是:虚拟的存在,是不能产生任何的相互作用的,真正产生相互作用的,只是与之对应的“意识”。 正确理解虚拟世界含义的引导性提问。 问题1.您是怎么看待“迷信的人相信有鬼存在”这样的事的? 回答: 1-1.我就是信迷信的,真的是有鬼的。 1-2.我不信迷信,我觉得没有鬼,鬼是迷信的人虚构的。 1-3.我没有什么看法,反正一部分人相信有鬼,另一部分人相信没有鬼,我是再另一部分的人之一,有鬼没鬼都无所谓,有也可以,没有也无妨。 分析:不管如何回答,“一部分人相信有鬼存在”是一种事实,这是任何回答都不能否定的。于是,可继续提问。 2.为什么会有一部分人相信有鬼存在呢? 2-1.因为,他们认为,只有相信有鬼的存在,才能解释一些别人无法解释通的事情。 2-2.因为他们确实得到过某种体验,这种体验本身就告诉他们,是有鬼的。 2-3.因为他们,不仅是他们,还有全世界的科学家,都解释不了某些现象。 分析: 不管怎么回答这个问题,一个共同的事实可以确定的是:在相信有鬼的这部分人的意识中,是确实有“鬼”这种意识存在的。不管现实中是否真的有鬼,但“有鬼”这种意识是存在于这群人的意识中的,并会影响这些人的日常行为、判断和语言表达的。 3.那么,至少"在意识中有鬼的概念存在"的人,相信鬼真实存在的逻辑是什么呢? 不管是某种特殊的直接体验也好,某种道听途说的间接体验也好,相信鬼真实存在的逻辑是:只有假设有鬼的情况下,他们这些体验才能得到他们自认为是合理的解释,如果假设没有鬼,就无法解释这些特殊的体验。 分析:假设、求证(求得一种自认为合理的解释,或不承认假设就得不到自认为合理的解释)是一般的认定事实的方法。相信有鬼的人,也自然要采用这样的方法来求证。排除求证的过程的合理性先不谈,相信有鬼的人,自然,先是承认了一个“有鬼的假设”,也就是,必定有一个假设中的“真实的鬼”是存在的,这个假设中的鬼,与这些人头脑意识中的“鬼”是不同的。一个是被认为与意识主题无关的“假设真实”的存在,另一个就是意识主体自身意识中的存在。 “假设真实存在”也是一种存在,这就是“虚拟存在”,这种虚拟存在,是“意识存在”的反射结果。这种“虚拟存在”是空虚的,是没有物质和能量载体的,不会直接产生任何的物理、生理和心理的作用,实际产生这些作用的是反射它出来的“意识”。 即便是“假设的真实”能够得到任何意义上的“求证”,我们可以认为原先假设的,确实可以找到“真实”的例证,我们原先的假设,也依然还是存在的,我们只是找到了“假设存在”与“真实存在”的两种存在的一致呼应而已。 所以,“假设不以意志为转移的存在”与“真正不以意志为转移的存在”都是“不以意志为转移的存在”,这是与第三者——“在意识上本身就认为是以意志为转移的存在”共同的区别。前二者又有不同的是:一个是虚构的,一个是真实的。 虚拟的世界不会直接参与真实世界的相互作用,而是产生虚拟世界的意识参与了真实世界的相互作用,我们只是混淆了虚构世界和产生虚拟世界的意识而已。 我们相信“鬼”这种东西是不存在的,但迷信的人却是相信有“鬼”的。 实际上,这样的分歧不是不可以解决,只要把“鬼”当作假设的存在,就解决问题了。假设的存在,就是虚拟的存在,就是虚拟世界的事物。 假设的存在,是没有任何物质和能量为载体支撑的。 我本来希望晓辉能提出这个疑问:说“虚拟的存在”没有相互作用或信息支撑,似乎说不过去。“鬼”虽然是不存在物质和能量载体的,但还是可以“吓人”的,还是有相互作用的,怎么能说虚拟存在是没有相互作用的呢? 所以,只要能回答出这个问题,就真正理解了我说的“虚拟世界”。 为什么“鬼”可以吓人,而“虚拟存在”却不能有相互的作用。 这正是“虚拟存在”和“意识存在”的区别! “吓人”的是“意识中的鬼”,是人先假设了“有鬼”的意识,这个“意识”是有信息、能量载体的,是可以产生相互作用的。 但这个意识所投射产生的“鬼”的虚拟假设,只是一个虚幻的存在,实际是根本没有的、不存在的事物,它自身是不能直接产生任何作用的。 这样,把意识和虚拟假设区分开来,对“求真”是意义重大的,当然,还是要依靠意识来完成这个“求真”过程,这正是“意识”觉醒的机会所在。 “意识”有这么一个特性:它总是试图构造更完美的虚拟世界,但却永远无法触及虚拟世界,它只能通过对自身的检验来“感觉”虚拟世界是否更加完美了。 当然,“虚拟世界”中,有“鬼”这种虚拟存在,是损害的虚拟世界的“完美”的,所以,“虚拟世界”本身,也是一个不断被完美塑造的世界,只有理想的虚拟世界,才是完美的虚拟世界,也就是柏拉图世界。
个人分类: 信息探索|5283 次阅读|8 个评论
“面向对象软件工程”讨论题
求新 2010-12-23 20:47
请结合以下各个方面比较传统软件工程与面向对象软件工程的异同,说明面向对象软件工程的特点是什么。 传统软件工程 面向对象软件工程 技术可行性认证 考虑已有的面向对象模型及程序部件、构件、中间件的可应用性、待扩展与待适应问题;分析需要新开发的部件、构件、中间件的难点与技术可行性 经济可行性认证 在考虑已有的面向对象模型及程序部件、构件、中间件、框架等可复用软件的情况下分析新系统成本构成;分析新扩展或新开发的部件、构件、中间件在今后软件开发中的意义、作用与经济价值。 瀑布模型、原型法 面向复用的开发方法 用部件系统搭建系统原型的意义与方法 项目计划与项目进度的主要时间与成本在程序代码设计与系统正确性、完善性维护 项目计划与项目进度的主要时间与成本在需求分析、建模、建库与建表及系统扩展性维护 同类系统比较与分析 工作流程图、数据流程图、 IPO 图 用例图、类图及说明文档 需求管理重点在数据需求变更、界面变更、代码表变更、接口与环境变更 需求管理重点在复用软件需求、界面变更、接口与环境变更 模块结构图与模块描述, U/C 矩阵 组件图与部署图与组件、网络等环境描述, U/C 矩阵 程序流程图,判定树与判定表 类图、时序图、协作图、活动图、状态图、判定树与判定表 用户界面设计 按对数据库处理类型区分系统并进行界面分析与设计(以部件库单表数据维护部件的设计过程、多表数据维护部件的设计过程、表格式数据维护部件的设计过程、查询类部件的设计过程、统计与报表等部件的设计过程、数据传送部件的设计过程、工作流控制部件的设计过程、系统维护部件的设计过程、系统控制类部件的设计过程为例总结说明 代码表的应用 代码表与历史数据的使用 子程序、宏、函数设计,强调模块化 类、继承、聚合、泛化及其他关联、多态的分析与设计,参数、属性选择与设定 集中式控制,水平下拉菜单与弹出式菜单控制,显式命令调用 集中式控制,水平下拉菜单、与弹出式菜单、图标、按钮、目录树等控制,工作流控制,事件驱动 通过代码改进追求易操作性、易维护性、易理解性、高安全性、高可靠性,运行高效 通过软件复用、软件分层等实现易扩展性、易维护性、高安全性、高可靠性。强调软件进化、开发过程高效率 结构化测试方法 面向对象测试方法 测试开发工具 各类面向对象开发工具,正向工程、反向工程
个人分类: 生活点滴|4180 次阅读|0 个评论
什么是设计模式?
yhc511025 2010-6-3 22:18
设计面向对象的软件是比较困难的,设计出可复用的面向对象软件更加困难。你必须找出定义出合适的类,按照适当粒度将它们组织起来,再定义出合适的接口,类层次及它们之间的相互关系。 对于新手来说,设计面向对象软件是一件比较痛苦的事情,如果要设计出一个复用性很好的软件几乎是不可能的。而有经验的面向对象设计者却能很轻松地设计出高内聚、低耦合的软件。这是为什么?因为有经验的设计者知道一些新手不知道的东西设计模式。 设计模式也就是前人总结出的一套经验,它针对不同的问题,提供不同的解决方案。如果能够掌握一些常用的设计模式,并能够熟练应用,那么就有可能设计出复用性较好的软件。
个人分类: 项目开发|5053 次阅读|7 个评论
软件设计师考试总结
yhc511025 2010-6-1 22:58
前一阵子参加了软件设计师的资格认证考试,考完后感觉比较好。2个月的努力总算没有白费,现在就等成绩出来了。 软件设计师的考试分为上午和下午。上午 有75道选择题,每题1分, 主要是考察基础知识,包括计算机系统知识、编译原理相关知识、操作系统、软件工程、网络基础知识、多媒体基础知识、数据库技术基础、数据结构与算法、面向对象设计、计算机英语、标准化及知识产权基础知识等。这次考试占比重较大的内容有软件工程(17.3%),数据结构与算法(16%)及面向对象设计(16%),3者加起来占了试题的49.3%,几乎一半。 软件工程和数据结构与算法一直都保持较大的比例。而 面向对象设计的比重是逐年加大的,从03年的4%左右增加到现在的16%左右,主要因为是近年来面向对象技术不断发展,在软件开发中应用得越来越广。 下午 有5道题,每题15分, 主要考考生对相关知识的应用能力,一般包括数据流图,UML,数据结构与算法(也可能是操作系统中的算法和网络传输中的算法),数据库,C/C++/JAVE程序填空(任选一道)。今年下午试题中有两道比较奇怪的题。 一道是数据库应用的题,该题给出了一大堆繁琐冗余的信息,也就是建一个数据库所需要的信息。然后让考生补充完整E-R图和关系模式,基本算是让考生独立设计一个数据库。以往的数据库应用题要么给出完整的E-R图,要么给出完整的关系模式,让你补充完整其中一个。今年这道题的灵活性很大,有项目经验的考生做起来比较容易。 另一道是最后一道题,往年的最后一道题都是给出3道题( C/C++/JAVE程序填空 ),然后让你从中选一道来做。今年仅给出了一道C++,考生没得选择。考官的目的很明显要求考生至少要掌握一门面向对象的编程语言。 总结起来,上、下午试题有两点比较大的变化:1. 面向对象技术在软件工程中越来越重要,成为软件设计师必须熟练掌握的一门技术。2. 试题的灵活性增大,对考生解决实际问题能力的要求提高。
个人分类: 项目开发|5989 次阅读|7 个评论
软件开发中的水平思维与逻辑思维
yhc511025 2010-5-29 22:56
这两天在看一本关于思维方法训练的书,这本书里面探讨了一些水平思考的方法。闲着无聊,简单认识一下水平思维和逻辑思维。水平思维,顾名思义,它是一种发散的思维,与逻辑思维相对应。利用水平思维考虑问题,向横向思考,不按推理方式进行深入,得到一些可能解决问题的方式。而逻辑思维则是纵向思考,按照逻辑推理的方式层层深入,最后找到问题的解。 水平思维在面向对象软件开发过程中,比较适合于系统的初步建模阶段。在这个阶段,大部分项目都会进行头脑风暴,让开发人员想出尽可能多的可能解决方案,然后将这些方案进行分析对比,最后找出一种较好可行方案。而逻辑思维的在项目的后期工作中发挥重大作用。当确定方案之后,再按照方案进行细化,然后实现。这些工作都需要依靠较强的逻辑思维。 水平思维负责提供各种新奇的想法,逻辑思维负责去实现这些想法,这两者缺一不可。如果缺失了水平思维,那么你就没有创新,永远都只能按照一些固定的模式做事;如果缺失了逻辑思维,即使你有很多想法,你也可能永远一事无成,因为你缺乏解决问题的工具。总体说来,水平思维和逻辑思维是相辅相成的。
个人分类: 项目开发|7530 次阅读|7 个评论
空间数据挖掘与GIS集成及应用研究
热度 1 maokebiao 2009-5-28 08:42
摘 要: 阐明空间数据挖掘与GIS集成的优越性,分析空间数据挖掘与关系数据库系统的区别,介绍面向对象技术对空间数据挖掘和空间数据挖掘的常用算法.在此基础上介绍地理信息系统与空间数据挖掘工具及应用。 1. 毛克彪 , 覃志豪 , 李昕 , 李海涛 , 空间数据挖掘与 GIS 集成及应用研究 , 测绘与空间地理信息 , 2004, 27(1):14-18. pdf 下载: 空间数据挖掘与GIS集成及应用研究
个人分类: 星星点灯|4048 次阅读|3 个评论
面向对象的中医基础理论
luowenxin 2009-2-1 10:07
完成《面向对象的中医理论体系》的研究已近三年。研究用面向对象的观点,把中医基础理论分为四个层次。研究文章先后寄给上十家权威中医、中西医结合杂志社,竟然没一家敢发表。因文章涉及中医的核心问题,且观点太出格,不符合现在位的中医权威们的思路,编辑们总能找到一些理由,婉言谢绝。   多数回信,用计算机语言设计中医专家系统还可接受,说中医理论中有先进的计算机软件设计思想太夸张。或称因不懂计算机,对面象对象很陌生,不便发表。极少数年青主编认为,此项研究对当今中医理论研究具有指导意义,但有可能因此而产生中医基础理论危机,而有损杂志本身的利益,成为众矢之的而拒绝发表。更有趣的是有一家编辑部的几个编辑意见极不统一,持赞同意见和持反对意见的矛盾极其尖锐。 人们对世界的认识是分层次的,中医基础理论可分为四个层次。阴阳为第一层次,卫气营血气血精液为第二层次,经络脏腑为第三层次,症状,疾病为第四层次。辨证是在这四个层次上展开的。以往人们对中医理论的认识不分层次,糊里糊涂的认识,导致国家标准也是不清不楚的。中医基础理论可分为四个层次,是这项研究的重要结论,对今后中医的发展,具有重要作用。其实,所谓中医、西医,是一个人为的概念,是戴着有色眼睛的人们,人为的划分出来的概念。医疗的对象只有一个人,所以医学也是一门可以汇通的学科。 面向对象的中医基础理论 罗文新 1 何敢想 1 毛维伦 2 许腊英 2 罗锎 2 1 湖北中医学院附属医院 2 湖北中医学院 关键词:面向对象 类 中医基础理论 四级辨证 中图分类号: R2 文字标识码: A 在计算机设计中,把任何感兴趣的、或要加以研究的事物、概念都统称为对象。按照人类认识世界的方法和思维方式来分析、解决这些对象的问题,就叫面向对象。具有相同特性和共同用途的一组对象抽象成为类。 人们通过智力模型来理解世界。构造世界各部分的智力模型是一个简化的概念。它表示某些事物是如何运作的。面向对象就是这样一种模型。 为了模拟人的思维方式,计算机软件设计者们花费了几代人的时间。近代,面向对象的思想是结构化、模块化、数据抽象、信息隐藏、知识表示、并行处理等各种概念的积累与发展。计算机软件高度发展的今天, 面向对象 (Object) 设计 已成为计算机软件设计的主流,已逐渐成为人们研究非线性世界、探索某些复杂系统的有力工具。 当软件发展已经相当完善今天,回过头来用面向对象的眼光来看祖先留下的遗产时,我们惊异的发现,中医基础理论,竟然包含有现代人工智能思想的雏形,甚至包含有计算机最新软件设计思想,特别是包含有新近发展起来的全套的面向对象软件设计思想 1 . 中医理论具有对象类的所有特征: 1.1 抽象 抽象是强调实体的本质、内在的属性,而忽略一些无关紧要的属性。人们通过构造世界各部分的智力模型来理解世界。智力模型是一个简化的概念,它必须在比那些模仿的系统简单才有效,它抽象出必需的要素,而忽略一些无关的要素,并且允许增加深一层抽象概念。如阴阳、表里、经络、卫气营血、藏象等,都是抽象的概念。甚至五脏六腑,不仅仅是解剖内脏的概念,而且是内脏器官、功能及有关临床特性的抽象概念。 1.2 .封装(信息隐藏) 封装性是指软件部件内部有明确范围及外部边界。内部实现与外部可访问性分离,内部实现过程及其变更不影响外部访问。方法和实现被包含在隐藏细节的黑箱内。从中医的病因至中医证候的各个中间环节,均处于不同层次、不同类别的黑箱中。 1.3 继承。 继承是父类和子类之间共享数据结构方法的机制。我们说,一个新类继承了父类的所有数据结构和行为,除了这个新的类包含了额外的东西外,几乎与原来那个类完全一样。一个子类为了定义它自己独特的对象,通常增加自己的行为。 中医学中,父类(基类或称超类)是阴阳类。在此基础上,继承出气血类,再继承出经络、五脏六腑类等。五脏证候中仍包含有阴阳的全部概念。 1.4 多态性 多态性是指两个或更多个对象响应同一消息的能力。如肝类的证候中,可收到来自阴阳超类的消息,肾类的证候中,可收到来自阴阳超类的消息,最后可产生肝肾阴虚的结论。 2 .中医整体的对象模型 我们首先建立面向对象的阴阳父类,并按层次,分级建立各级子类。在完全模拟八纲的基础上,建立五脏六腑的子类。然后按五行生克,建立不必知道生理功能 ( 黑箱 ) 的结构模型。用面向对象的类所建立起来的网络结构与中医基础理论中的阴阳、藏象网络结构完全相同。 建立包括八纲、卫气营血、经络、证候、藏象及病因、药性等全部中医理论的对象模型。以人为对象,按四个层次划分对象类,结合致病因素所组织的类,构成了复杂的多级子类系统。中医整体模型如下: 中医类 中药类 类分级 阴阳类、表里寒热虚实类 四性、五味 父类 病因类,气血精液类,卫气营血类 归经 一级子类 经络类,奇经八脉类,脏腑类 补益、清热、平喘等 二级子类 证候类 汤头,君臣佐使 三级子类 疾病类 四级子类 症状类、其它类。 3 .用面向对象的思想来分析、设计中医基础理论的意义 近代,面向对象的思想最初出现于挪威奥斯陆大学和挪威计算中心共同研制的 Simula67 语言中。它是结构化、模块化、数据抽象、信息隐藏、知识表示、并行处理等各种概念的积累与发展。随着位于美国加利福利亚 Xerox 研究中心推出的 Smalltalk-76 和 80 语言,面向对向的程序设计方法得到迅猛的发展。由 Bell 实验室推出的 C++ 语言更是一种面向对象的强类型语言,使面向对象的概念在人工智能、神经网络等方面得到了更广泛应用。 按专业要求来说,由于计算机软件理论与中医基础理论相距太远,两者不易完全贯通,很少有人理解最先进的计算机软件设计理论与最古老的中医学理论会有什么关系。仔细研究了中医理论的整个结构和证候诊断的思维过程。用面向对象的方法全面模拟中医理论后,一个全新的中医学展现在我们面前: 3.1 . 面向对象的思想全面、直截地、用现代语言说明了中医核心问题。 中医理论中包含结构化、模块化、数据抽象、信息隐藏、知识表示、并行处理等各种概念。一直以来,很难用单一学科的知识或理论,说明中医的这些复杂概念。 一般人认为中医不可能建模,或者不能用完全还原的方法分析中医理论。目前尚无人能用现代语言,全面、直截地说明阴阳学说、经络学说、证候理论、藏象理论等中医的核心问题的实质。 现在,我们将其用面向对象的类建模,并且,我们用完全还原分析的方法揭示了阴阳、卫气营血、藏象的本质就是 以人为 本的 对象 类。 中医基础理论中的抽象、封装、继承、多态等多种概念,具有对象类的所有特征。如阴阳、表里、经络、卫气营血、藏象等,都是抽象的概念。五脏六腑,不仅仅是解剖内脏的概念,而是简化的内脏器官、功能及有关临床特性的抽象概念和智力模型。从中医的病因至中医证候的各个中间环节,均封装在不同层次、不同类别的黑箱中。阴阳类继承出气血类,再继承出经络、五脏六腑类等,肝类的证候中,可收到来自阴阳超类的消息,肾类的证候中,可收到来自阴阳超类的消息,最后可产生肝肾阴虚的结论。 面向对象的思想很好的解决了中医的理论与现代医学理论脱节的矛盾,它本身就包含结构化、模块化、数据抽象、信息隐藏、知识表示、并行处理等各种概念。用它全面、直截地说明了中医基础理论的核心问题。 3.2 .中医学可将现代西方医学完全纳入自己的范畴。 对象类中的信息是隐藏的,我们只需讨论输出和输入,即消息和结果。对象内的运行机制可以随着软件的不同而不同或完全更换。从中医的病因至中医证候的各个中间环节,均处于不同层次、不同类别的黑箱中。这样我们就可把中医黑箱中的病机整个更换,代之以全新的现代医学解释,或者在目前的病机中加入现代医学的病理概念,中医与现代西方医学就完全接轨了。中医的现代化也完全解决。 中医类 病机分级 类分级 阴阳、表里寒热虚实类 阴阳失调 父类 病因类,气血精液、卫气营血类 气血失常 一级子类 经络类,奇经八脉类,脏腑类 经络病机、脏腑病机等 二级子类 证候类 证候病机 三级子类 疾病类 各病的病理解剖、病理生理 四级子类 症状类。 中医的分级分类法不仅完全解决了证候标准化问题。而且解决了中医被西医同化的问题。 长期以来,中医研究者们害怕中医被西方医学同化,一直不敢把现代已经确定的疾病全面纳入中医范畴。特别是在高等中医教育中,不管是基础理论、诊断还是内科,只是在各论中介绍了屈指可数的几个病,致使学生从学校的课本中仅能学到极少的西方现代医学知识。刚毕业的学生不管是本科生还是研究生,往往连一般化验单都难看懂。 其实,老祖先们早已为我们确立了各种疾病的辨证方法。像感冒、破伤风、痢疾等,这些疾病及其辨证方法,很早就出现在老祖宗们的书中只是我们没有认识而已。多级辨证将现代医学疾病全部纳入四级辨证。这就为中医理论全面接受西医理论奠定了基础。重新整理后的对象模型如下: 中医类 中药类 类分级 阴阳类、表里寒热虚实类 四性、五味 父类 病因类,气血精液类,卫气营血类 归经 一级子类 经络类,奇经八脉类,脏腑类 补益、清热、平喘等 二级子类 证候类 汤头,君臣佐使 三级子类 疾病类 抗菌、抗癌、抗休克等 四级子类 其它类。 3.3 .用面向对象的方法来分析中医系统理论时,发现中医现存的证候分类中还存在许多缺陷,还应进一步完善。 并且花费了大量的人力,物力,财力来研究各种证候,制定了一系列标准。由于理论问题没解决,经过多年的定性或定量化规范后的一系列中医证候诊断标准在学术界并未达成共识,标准一直得不到统一,更难得到推广。就面象对象和人工神经网络的观点看来,目前所有这些标准,相当部分都是错的。标准中,病证同称、证症不分、证型繁杂、证名不全、层次不清混乱状况大量存在。错误的关键就在于目前还没有了解中医理论实质就去制定标准,实施规范的技术方法不能全面反映中医理论体系的真实面貌。 解决了阴阳理论、藏象的理论的层次、网络结构后,证候的研究就有了全面的轮廓,混乱状态也就迎刃而解了。证候应划分为父类和三级子类为基础的四级辨证。目前的标准把几个不同级别的证、症、病放在一起,哪能不出现大错误。 按面向对象的观点,将对象分级的分级辨证如下: 中医类 辨证 类分级 阴阳类、表里寒热虚实类 阴虚 父类 病因类,气血精液类,卫气营血类 气血虚 一级子类 经络类,奇经八脉类,脏腑类 肝虚 二级子类 证候类 肝血虚、肝肾阴虚 三级子类 疾病类(感冒) 风寒感冒 四级子类 1 症状类(黄疸) 阳黄 四级子类 2 3.4 . 中医学说完全是以面向对象的类为基础,以特殊的网络结构为特征而建立起来的具有人工智能雏形的先进的医学理论。 中医药学理论体系与现代医学的理论体系有很大的不同。整个体系由阴阳学说、精气学说、卫气营血学说、经络学说、藏象五行学说、证候理论等组成。这些理论构成了整个中医理论体系的核心。如何使这些理论与现代化接轨,是中医现代化的关键的环节。这些学说是与现代西方医学最难相容的医学理论,也是现代西方医学研究者们难以理解的理论问题。如何诠注这些理论,成了中西方学者面临的巨大难题。 一直以来,大多数国外现代西方医学研究者们认为,所有这些理论只不过是中医的一种对病证的古典看法,更有人打着反伪科学的旗号来反对中医理论。国内现代西方医学研究者们具有与国外学者大致相同的观点。 中医中药的专业研究者们则总强调中医是一整套完整体系的医学,它不同于现代西方医学。究竟有什么不同,因拿不出令人信服的可靠的理论、实验,或者模型来阐明机理,划定范畴,也只好把这些理论解释为具有整体观的、反映客观世界的哲学思想。这些学说的实质是什么,它们之间有什么关系,能不能用现代科学的观点来说明这些理论,如何用现代科学的观点说明这些理论,特别是现在科学突飞猛进发展,知识爆炸、不断更新的年代,是目前中医界所面临的生死存亡的大问题。 中医理论的复杂性为其实质性的研究增加了相当大的难度。从 80 年代起,就有人用计算机理论处理中医问题。但因计算机软件理论发展还处于初期,面向对象的观念还未被大家认识,人工智能的观念还未形成。多数研究者并不了解中医本身就是面向对象建立起来的理论,且有它特有的规律,只是机械地用计算机解决中医的一个或几个问题。而且对中医的发展也很难起到促进作用。 初次接触面向对象的抽象概念时,是难以理解。也是众多科技工作者们斥责中医为不科学的最大因素。 用面向对象的思想来看中医基础理论时,发现中医基础理论包含有现代人工智能思想的雏形及计算机最新软件设计思想,特别是包含有新近发展起来的全套的面向对象软件设计思想和人工神经网络思想。 中医的各种学说,甚至整个中医理论,都是由类对象构建起来的先进的医学理论。以阴阳、经络、藏象理论为对象的类具有特殊的组织结构。其层次结构复杂。 八纲、卫气营血及其它脏腑间的关系,既有平行关系,又有隶属关系,用面向对象的方法和人工神经网络的多层系统能很好的表达它们的关系。我们使用对象类来来建立这种关系,建立了这些网络关系的表达式。基于黑箱结构的以对象类为基础的中医整体人工神经网络就成功实现了。 不管人的主观愿望如何,也不管老的思想多么保守,现代科学知识的海洋肯定会不断渗入传统的中医理论。要么在保持原有体系的前提下充分接受新理论、新思想,要么就被现代科学的海洋所吞没。面向对象的理论是在全面肯定中医传统理论的基础上,用全新的思想诠注了中医理论,使原被西方医学认为落后的、陈旧的、过时的理论一举成为最先进的具有人工智能思想的医学理论。 3.5 .面向对象的方法为中医的发展明确了前进方向。 现实世界是复杂的。对现实世界的观察越接近,看到的东西就越复杂。层层细节是无止境的。面向对象的方法使我们可从宏观着手,即从阴阳、经络、藏象开始,一直到证候、症状、疾病、器官、细胞等等,层层分析下去。为中医的研究,极大的拓展了发展方向。 面向对象与人工神经网络构成的中医学为中医的全面现代化奠定了基础。在古老的中医学中引入现代面向对象的思想,必将引起医学界振动和中医界的一场革命。 面向对象的中医基础理论
个人分类: 未分类|4342 次阅读|1 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-6-11 15:52

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部