目录
前提
区别简述
面向过程(Procedure Oriented):以过程为核心,强调事件的流程、顺序,如:C语言。
面向对象(Object Oriented):以对象为核心,强调事件的角色、主体,如:C++、Java。
面向对象
把某些步骤里面共同的行为抽象出一个类,每次需要使用这个行为的时候就直接调用这个类好了.
面向过程
按照事情的步骤用函数写出来,然后一步步的按照先后顺序实现,最后使用的时候依次调用就行.
区别
1.思路不同
2.特点不同
3.优势不同
面向过程是直接将解决的问题分析出来,然后用函数将步骤一步一步实现,然后再一次调用就可以了;
面向对象是将构成问题的事物,分解成若干个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在解决问题过程中的行为。
面向过程思想偏向于我们做一件事的流程,首先应该做什么,其次做什么,最后做什么。
面向对象思想偏向于了解一个人,这个人的性格,特长是怎么样的,有没有遗传到什么能力,有没有家族病史。
面向过程是一种以过程为中心的编程思想,面向过程编程是基于冯诺依曼模型的。
面向过程优点
流程化使得编程任务明确,在开发之前基本考虑了实现方式和最终结果,具体步骤清晰,便于节点分析,效率高,面向过程强调代码的短小精悍,善于结合数据结构来开发高效率的程序。
面向过程缺点
需要深入的思考,耗费精力,代码重用性低,扩展能力差,后期维护难度比较大。
面向对象优点
易维护,易扩展,易复用,有封装、继承、多态的特性、更容易设计出耦合的系统。
面向对象缺点
性能没有面向过程高
如何理解面向对象的三个特性
封装
将属性和方法都放在一个类里,而且还可以通过访问类的权限属性给区分开,用户不需要知道我这个类中的属性和方法到底怎么写的,直接调用使用即可。更加安全,不想要释放的功能,可以直接做成私有。
继承
就是把之前已经实现好的代码或者方法通过继承的方法拿过来使用,能节省大量的代码量,符合代码设计里面的继承优秀代码特性。
多态
由于可以继承多个类,能够组合成多种特性,但多态的关键是覆盖,就是同一个方法可以用不同的方式去实现,展现出多态性,就是方法和属性有多种形态。
举例说明一
1.完成一个编程题目,需要经过以下步骤:
第一步:看题目
第二步:思考
第三步:若思考时间大于30分钟,进入循环环节,若小于30分钟问题已经解决
第四步:询问室友,若给答复进入第二步,否则进入下一步
第五步:询问同学A,若给答复进入第二步,否则进入下一步
第六步:询问同学B,若给答复就进入第二步,否则进入下一步
..........
第n步:询问老师,得到答复,进入第二步
2.用面向过程实现
与1中步骤一致
3.用面向对象实现
从1的步骤可知,询问题目的对象可以是室友、同学A、同学B.....老师
因为解答问题的人之间有相同的行为,都是为了回答问题,所以可以抽象一个解答者类,这个类来代表解答问题的人,
调用类中方法的不同(代表不同类型的问题解答者),若类中方法返回的结果是true,则进入第二步
举例说明二
人把大象装进冰箱:
面向过程:
函数1: 打开冰箱(){人站在冰箱前,打开冰箱,冰箱开到30度角的时候,冰箱的灯打开了....}
函数2:储存大象(){大象先迈出左腿,再迈出右腿,考虑冰箱能不能装的下...}
函数3:关闭冰箱(){人站在冰箱前,关闭冰箱,冰箱关到30度角的时候,冰箱的灯熄灭了....}
面向对象:
人{
打开(冰箱) {
冰箱.打开();
}
储存(大象){
大象.进入(冰箱);
}
关闭(冰箱){
冰箱.关闭() ;
}
}
冰箱{
打开(){}
关闭(){}
}
大象{
进入(冰箱){}
}
面向过程—>面向对象,其实就是执行者到指挥者的一个过渡。
二者相辅相成,并不是对立的。解决复杂的问题,通过面向对象方式方便我们从宏观上把握事物之间的复杂关系,方便我们分析整个系统,具体到微观操作,仍然使用面向过程方式来处理。
面向对象编程的本质是:以类的方式组织代码,以对象的组织(封装)数据。
面向对象三大特性:继承、封装、多态
1.继承:子类继承父类非私有的属性和方法,子类可以添加自己的属性和方法,子类可以重新定义父类的方法。
1)注意:Java中是单继承,即一个子类只能继承一个父类;Java中object类是所有类的直接或间接父类;每一个子类被实现按时(new),父类会在它之前实现(被new)。
构造函数不能被继承,子类可以通过super()显式调用父类的构造函数;创建子类时,默认调用父类的无参构造函数;如果父类没有定义无参构造函数,子类必须在构造函数的第一行使用 super()显式调用(先父后子)。
2)为什么需要继承呢?
第一,代码复用;第二,父类的引用变量可以指向子类对象。
2.封装:即隐藏对象的属性和实现方法,仅对外提供公共的访问方法。
1)为什么需要封装呢?
封装符合面向对象设计的单一性原则,一个类把自己该做的事情封装起来,而不是暴露给其他类去处理,当内部的逻辑发生变化时,外部调用不用因此而修改,它们只调用开放的接口,而不用去关心内部的实现。
2)实现:将属性私有化;仅提供公开的方法(一个负责获取内容(get),一个负责修改内容(put))访问私有属性。
3)优点:提升了代码的安全性和隐私性;能减少耦合;类内部的结构可以自由修改;
3.多态:一个对象在不同时刻体现出来的不同状态(一对多的关系)(父类引用子类对象)
1)实现:
重写:子类重写父类方法的实现,它是一种垂直层次关系。父类的引用变量不仅可以指向父类的实例对象,还可以指向子类的实例对象。当父类的引用指向子类的对象时,只有在运行时才能确定调用哪个方法。
重载:指一个类中,存在方法名相同,但参数(个数、顺序、类型)不同的方法,在编译时就可以确定到底调用哪个方法。它是一种水平层次关系。
特别注意:只有类中方法才有多态的概念,类中成员变量没有多态的概念。
2)重写和重载的区别?
重写是一种垂直关系,它是子类重写父类的方法,要求结构相同;而重载是一种水平关系,它是类内部书写多个相同名称的方法,它们通过形参列表来区分。
3)在形参声明过程中,一般会声明的范围比较大,就可以传递父类也可以传递子类,代码的通用性就比较强。
4)多态可以分为两种类型:编译时多态(方法的重载)和运行时多态(方法的重写)。
运行时多态依赖于继承、重写和向上转型,向上转型是自动的,Father f = new Children(),不需要强转;向下转型需要强转,即Children c =(Children) new Father()。
5)Java中重写的两同两小一大规则:
a. 方法名相同、参数列表相同;
b. 子类方法返回类型<=父类方法返回类型
c. 子类方法抛出异常<=父类方法抛出异常
d. 子类方法访问权限>=父类方法访问权限
声明为final和static的方法不能被重写;如果一个方法不能被继承,则不能被重写。
面向对象的六个基本原则(设计模式的6个基本原则)
单一职责原则(Single-Resposibility Principle):是指一个类的功能要单一,一个类只负责一个职责。一个类只做它该做的事情(高内聚)。在面向对象中,如果只让一个类完成它该做的事,而不涉及与它无关的领域就是践行了高内聚的原则。
开放封闭原则(Open-Closed Principle):软件实体应当对扩展开放,对修改关闭。对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。对修改封闭,意味着类一旦设计完成,就可以独立其工作,而不要对类进行任何修改。在开发阶段,我们都知道,如果对一个功能进行扩展,如果只是一味地对方法进行修改,可能会造成一些问题,诸如可能会引入新的bug,或者增加代码的复杂度,对代码结构造成破坏、冗余,还需要重新进行全面的测试。那么该怎么解决这些问题?很简单,这就需要系统能够支持扩展,只有扩展性良好的系统,才能在部进行修改已有实现代码的基础上,引进新的功能。
里氏替换原则(Liskov-Substituion Principle):任何使用基类的地方,都能够使用子类替换,而且在替换子类后,系统能够正常工作。子类一定是增加父类的能力而不是减少父类的能力,因为子类比父类的能力更多,把能力多的对象当成能力少的对象来用当然没有任何问题。一个软件实体如果使用的是一个基类,那么当把这个基类替换成继承该基类的子类,程序的行为不会发生任何变化。软件实体察觉不出基类对象和子类对象的区别。
接口隔离原则(Interface-Segregation Principle):即应该将接口粒度最小化,将功能划分到每一个不能再分的子角色,为每一个子角色创建接口,通过这样,才不会让接口的实现类实现一些不必要的功能。建立单一的接口,不要建立臃肿的庞大的接口,也就是说接口的方法尽量少。接口要小而专,绝不能大而全。臃肿的借口是对接口的污染,既然接口表示能力,那么一个接口只应该描述一种能力,接口也应该是高度内聚的。
依赖倒置原则(Dependecy-Inversion Principle):即我们的类要依赖于抽象,而不是依赖于具体,也就是我们经常听到的”要面向接口编程“。(该原则说的具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代)。依赖倒置原则的本质就是通过抽象(抽象类或接口)使各个类或模块的实现彼此独立,不相互影响,实现模块间的松耦合。减少类间的耦合性。
合成/聚合复用:优先使用聚合或合成关系复用代码。