面向过程和面向对象
面向过程
关心的是我该如何做
一步步实现这个功能
面向对象
关心的是我该让谁去做
去调用这个对象的操作来实现这个功能
类
一个类定义了一组大体上相似的对象,一个类所包含的方法和数据描述一组对象的共同行为和属性,把一组对象的共同特征加以抽象并存储在一个类中是面向对象最重要的一点,是否建立了一个丰富的类库,是衡量一个一个面向对象程序设计语言成熟与否的重要标志
类是在对象上的抽象,对象是类的具体化,是类的实例(Instance),在分析和设计时,通常把注意力集中在类上,而不是具体的对象,也不必逐个定义某个对象只需要对类做出定于,面对类的属性进行不同赋值即可得到该类的实例化对象。
类可以分为三种:实体类、接口类(边界类)和控制类。实体类的对象表示现实世界中真实的实体,如人、物等。接口类或者说边界类的对象为用户提供了一种与系统交互的方式,分为人和系统两大类,其中人的接口可以是显示屏、窗口、Web窗体、或显示控制类、条形码、二维码或者用户和系统交互的其他方式。系统接口设计到把数据发送到其他系统或者从其他系统接受数据。控制类的对象用来控制活动流,充当协调者。
有些类之间存在一些特殊关系,即一些类是某个类的特殊情况,某个类是一些类的一般情况。这是一种 is-a 关系。即特殊类是一种一般类。例如汽车类、轮船类、飞机类都是一种交通工具类。特殊类是一般类的子类,一般类是特殊类的父类。这种关系也可以在嵌套中形成一种层级关系。通常把一个类和这个类的所有对象称为 类及对象 或对象类
对象
在面向对象的系统中,对象是基本的运行时的实体,它既包括的数据(属性),也包括作用于数据的操作(行为)。所以,一个对象把属性和行为封装成一个整体。封装是一种信息隐蔽技术,它的目的是使对象的使用者和生产者分离,使对象的定义和实现分开。从程序设计者来看,对象是一个程序模块;从用户来看,对象为他们提供了所希望的行为。在对象内的操作通常称之为方法。一个对象通常由对象名、属性、方法三个部分组成。
在现实世界中,每个实体都是对象,如学生、汽车、电视机和空调等都是现实世界中的对象。每个对象都有它的属性和操作。如电视机有颜色、亮度、灰度频道等属性,可以有切换频道、增大音量、减小音量等操作。电视机的属性表示电视机当前的状态,而这些属性只能通过其提供的操作进行改变。电视机的各组成部分,如显像管、电路板等关系零件都封装到电视机里面,人们不知道耶不关心电视机是如何实现该操作的。
消息
对象之间进行通信的一种构造叫做消息。当一个消息发给某个对象时候,包含要求接收对象去执行某些活动的信息。接收到消息的对象经过解释,然后予以响应。这种通信机制叫做消息传递,发送消息的对象不需要知道接受消息的对象如何对请求予以响应。
方法重载
方法同名但是方法参数个数不同,或方法参数类型不同,或方法参数类型顺序不同 都是方法重载。
继承
继承是父类和子类之间共享数据的机制。这是类之间的一种关系,在定义类和实现一个类的对象的时候,可以在定义和实现类的时候,可以在一个已经存在的类的基础上进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
一个父类可以有多个子类,这些子类都是父类的特例,父类描述了这些子类的公共属性和方法,一个子类可以继承它的父类或先祖类中的属性和方法,这些属性和操作在子类中不必定义。子类中还可以定义自己的属性和方法。
多态
在收到消息时,对象要予以响应。不同的对象收到同一消息可以产生完全不同的结果,这一现象称为多态(Polymorphism)。在使用多态的时候,用户可以发送一条通用消息,而实现的细节则由接收的对象自行决定。这样,同一条消息可以调用不同方法。
多态有不同的形式,Cardelli 和 Wegner 把它分为四类,如下所示。其中参数多态和包含多态被称为通用多态,过载多态和强制多态被称为特定多态
多态分为:
通用的多态:
参数多态
包含多态
特定的多态
过载多态
强制多态
参数多态是英语比较广泛的多态,被称为最纯的多态。包含多态在许多语言中都存在,最常见的例子就是子类型化,即一个类型就是另一个类型的子类型。过载(Overloading)多态是同一名字在不同的上下文中所代表的含义不同。
静态、动态绑定
绑定是一个把过程调用和响应调用所需要执行的代码加以结合的过程。在一般的程序设计语言中,绑定是在编译时进行的,叫做静态绑定。动态绑定则是在运行时进行的,因此,一个给定的过程调用和代码的结合知道调用发生时才进行。
动态绑定是和类的继承以及多态相联系的。在继承关系中,子类是父类的一个特例。所以父类对象可以出现的地方,子类对象也可以出现。因此在运行过程中,当一个对象发送消息请求服务时,要根据接受对象的具体要求情况将请求的操作与实现的方法进行连接,即动态绑定。
面对对象设计原则
单一职责原则(Single Responsibility Principle, SRP) 。就一个类而言。一个仅有一个引起它变化的原因。即当需要修改某个类的时候原因有且只有一个,让一个类只做一个类型的责任
开放-封闭原则(open & clone Principle, OCP)。软件实体(类、模块、函数等)应该是可以扩展的,即开发的;但是不可修改的,即封闭的。
里氏替换原则(Liskow Substitution Principle,LSP) 。子类型必须能够替换掉他们的基类型。即父类可以出现的地方,都可以用子类的实例来赋值给父类型引用,当一个子类的实例一个能够替换任何其超类的实例时,它们之间才具有一个 is-a 关系
依赖倒置原则(Dependence Inversion Principle,DIP)。抽象不应该依赖细节,细节应该依赖抽象。即。高层模块不应该依赖于低层模块,二者都应该依赖抽象。
接口分离原则(Interface Segregation Principle,ISP) 。不应该强迫用户依赖于它们不用的方法。接口属于客户,不属于它所在的类层级结构。即:依赖于抽象,不要依赖于具体,同时在抽象级别不应该对于细节的依赖。这样做的好处就在于可以最大限度地应对可能的变化。
共同封闭原则(Common Closure Principle,CCP)。包中所有类对于同一性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中所有类产生影响,而对于其他包不造成任何影响
共同重用原则(Common Reuse Principle,CRP)。一个包中所有类应该是共同重用的,如果重用了包中的其中一个类,那么就要重用包中的所有类。
软考-面向对象
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法