初识面向对象
本人最近想着学习一下设计模式方面的东西,翻了不少资料,整理了一下自己的心得,来跟园子里的朋友交流一下,如有不妥之处请各位批评指正。
面向对象程序设计是目前最为流行的编程方式之一,其发展可谓如日中天,园子里的大牛对其都有一些独到的见解,小弟拜读之后感受颇深。
面向对象定义:
首先根据客户需求抽象出业务对象,然后对需求进行合理分层,构建相对独立的业务模块,之后设计业务逻辑,利用多态、继承、封装、抽象的编程思想,实现业务需求;最后通过整合各模块,达到高内聚低耦合的效果,从而满足客户要求。众所周知,面向对象最大的特点就是抽象、封装、继承和多态,利用它们可以写出优良的面向对象架构程序,反之,也可能是败笔之作。下面来介绍一下这几个概念:
抽象:
强调实体的本质、内在的属性,使用抽象可以尽可能避免过早考虑一些细节。
这篇博客中对抽象进行了解释:http://blog.csdn.net/houdy/article/details/778956
抽象的过程就是提炼存在于事物之间共同拥有的元素,而这些事物之间共同拥有的元素往往是这一事物区别于其他事物关键的东西,这些元素就构成了事物的本质。因此抽象使我们更接近于事物的本质。
抽象的思维方式使我们能够控制问题域或者系统的复杂度,从而使我们能够找到解决问题的方式。通常我们面临问题的细节比较繁琐,我们往往无从下手,而抽象的强大优势在于它可以使我们暂时忽略这些细节,先考虑这些简单的问题。根据抽象度的不同可以将问题域划分成不同的层次,抽象度越高,涉及到细节的东西就越少。因此我们更能够把握问题。
抽象是继承和多态的基础。在抽象过程中,我们获得的是事物本质的东西,独特的东西。所以抽象的事物与具体的事物之间是一种继承的关系,而他们之间的不同性可以通过多态来表现出来。
封装性(Encapsulation):
把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
另一种定义:隐藏属性、方法或者实现细节的过程,仅对外公开接口。直接点说面向对象的封装就是把不想或者不该告诉别人的东西封装起来,把可以告诉别人的公开。因此这就不得不说访问控制级别,不同语言提供的关键字有所不同,以C#为例共提供了public、protected、private、internal、protected internal五种访问级别。封装就是合理的使用这些关键字来实现的,因此在定义类的变量和方法时应该慎重考虑该成员的访问级别,对成员进行合理的封装。下面看这段实例代码:
public class Person
{
public string Name { get; private set; }
protected int age = 0;
internal void SetName(string name)
{
if (String.IsNullOrEmpty(name))
return;
this.Name = name;
}
}
我声明了一个Person类,该类有一个Name属性,你会发现,Name的属性访问器是公开的,而设置器是私有的,看到这里你就会明白了,因为一个人的名字是不能别别人随便修改的,但是他的长辈爷爷奶奶或者爸爸妈妈可以给他命名(假设他们跟Person在同一个程序集),因此我们有一个internal方法SetName,这样与Person位于同一个程序集的类就可以调用了。还有一个protected修饰的age属性,我们都知道年龄是一个人的隐私,尤其是女士,因此我们使用需要来将其隐藏起来,因此有人讲,我们可以用private来修饰age属性,但是考虑到将来会有Man、Woman来继承此类,我们应该使用protected。
封装的优点:
1.便于使用者正确、方便地理解和使用,防止使用者错误的修改系统属性。
2.清楚的体现了系统之间的松散耦合关系,提高系统的独立性。
3.提高软件的可重用性。
4.降低大型系统的构建风险,即使整个系统不成功,个别的独立子系统仍然有可用价值。
继承(Inheritance):
继承是软件重用的一种形式,他通过吸收现有类的数据(属性)和方法(行为),并增加新功能或修改已有功能来创建新类。通常我们将现实中的事物进行抽象,提炼事物当中共同的元素,将其作为抽象类或者接口,而具体的事物就可以通过继承来实现,具体的事物具有抽象事物的所有属性。
在父类和子类之间存在着继承和扩展关系,子类继承父类的属性和方法的同时还可以扩展出新的属性和方法,并且还可以覆盖父类中方法的实现方式。
有种说法“继承的目的是为了复用”,其实这个说法根本是错误的,但这个说法在开发人员当中相当流行。继承并不是为了复用,继承的根本目的是对现实世界进行更好的建模,容易复用只是优秀模型的一个必然结果而已。因此我们不能为了复用的目的而去使用继承,那么,我们应该如何去使用继承呢?
随着面向对象理论的发展,人们对继承存在着褒贬不一的说法,现代OO认为“组合优于继承”,一般来讲,这个说法是没有问题的,但是问题并不绝对,否则为什么继承会成为OO的三大支柱之一呢?所以存在即是合理的。(关于组合和继承的讨论我会在以后的文章中给出,欢迎大家批评指正。)有些情况下继承确实比组合要好,举个例子:开发过Winform程序的朋友应该知道Button、Form与Control之间的继承关系,如下两图所示:
你会发现Button类和Form类都继承自Control类,所以他们都是继承自Control的,然而这里使用继承就没有什么问题,根本原因就是这里存在着确定的is-a的关系,实践表明:如果语义上存在着明确的is-a关系,而且它们之间的关系是稳定的,则考虑使用继承,否则考虑使用对象组合。
多态(Polymorphsim):
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态。
多态有两种表现方式,一是同一个类中有多个名字一样但签名不同的方法;二是子类改写父类中方法的内部实现。