面向过程与面向对象及面向对象三大特性

今天复习一下面向对象的特性以及与面向过程的

#########################################################

今天复习一下面向对象的特性以及与面向过程的区别,并对其中的一些细节内容进行回顾!!!

#########################################################

一、面向过程与面向对象的区别?

面向过程:是一种以过程为中心的编程思想,分析出解决问题的步骤,然后用函数把这些步骤一步一步实现。面向过程编程中数据和对数据的操作是分离的。

  1)优点:性能比面向对象高,因为在类调用是需要实例化,开销比较大,比较消耗资源。

  2)缺点:没有面向对象易维护、易复用、易扩展。

面向对象:是将事物对象化,通过对象通信来解决问题。面向对象编程中数据和对数据的操作是在一起的。

  1)优点:由于面向对象有继承、封装、多态的特性,可以设计出低耦合的系统,使系统更更灵活,更易于维护。

  2)缺点:性能比面向过程低。

二、面向对象三大特性:继承、封装、多态

  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):即我们的类要依赖于抽象,而不是依赖于具体,也就是我们经常听到的”要面向接口编程“。(该原则说的具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代)。依赖倒置原则的本质就是通过抽象(抽象类或接口)使各个类或模块的实现彼此独立,不相互影响,实现模块间的松耦合。减少类间的耦合性。

  合成/聚合复用:优先使用聚合或合成关系复用代码。