面向对象编程

Posted by icoding168 on 2020-04-09 17:35:45

分类: Java  

面向对象编程(Object Oriented)是一种程序设计思想、软件开发方法。

面向对象程序设计方法是尽可能模拟人类的思维方式,使得软件的开发方法与过程尽可能接近人类认识世界、解决现实问题的方法和过程,也即使得描述问题的问题空间与问题的解决方案空间在结构上尽可能一致,把客观世界中的实体抽象为问题域中的对象。

面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

而面向对象程序设计以对象为核心,该方法认为程序由一系列对象组成。类是对现实世界的抽象,包括表示静态属性的数据和对数据的操作,对象是类的实例化。对象间通过消息传递相互通信,来模拟现实世界中不同实体间的联系。在面向对象的程序设计中,对象是组成程序的基本模块。

三大特性

面向对象编程有三大特性:封装、继承、多态。

封装

封装是指隐藏对象的内部实现细节,只保留有限的对外接口。

封装的目的就是“互不影响”,模块的设计者可以随便修改模块里面的实现而不影响调用者,调用者也能知道自己能碰哪些东西,只要遵守这个协议,调用者的代码就不会因为模块内部的实现变化而跟着变化。封装使得调用者不用关心模块的内部实现细节,减少了模块之间的耦合。

继承

通过继承创建的新类称为“子类”或“派生类”,被继承的类称为 “父类” 或“超类”、“基类”。 子类会继承父类的属性和行为,并且也可包含它们自己的属性和行为。也就是说, 子类无需重新编写代码就可以使用父类现有的功能,还能对这些功能进行扩展。除了实现代码重用和扩展, 继承的意义还在于声明某个类属于某一种类,继承是实现多态的基础。

Java 的继承

在 Java 中,可以使用 extends 和 implements 这两个关键字来实现继承。Java 不支持多继承,但支持多重继承。

多态

多态是指同一种事物表现出的多种形态。

在 Java 中,多态分为两种情况:编译时多态和运行时多态。如果在编译时能够确定执行多态方法中的哪一个,称为编译时多态,否则称为运行时多态。

多态的优点

提升代码的可扩展性和可替换性,降低代码之间的耦合度。可以让程序员写出通用的代码,以适应需求的不断变化。

Java 的重写和重载

重写是指子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变 。

重载是指在一个类里面,方法名字相同,而参数不同,返回类型可以相同也可以不同。

方法重载都是编译时多态,而方法重写表现出两种多态性,当对象引用本类实例时为编译时多态,否则为运行时多态。

Java 实现运行时多态的三个必要条件
  • 继承
  • 重写
  • 父类引用指向子类对象

五大原则

面向对象编程应遵循五大基本原则。

单一职责原则(Single-Resposibility Principle)

一个类,最好只做一件事,对一个类而言,应该仅有一个引起它变化的原因。

如果一个类承担的职责过多,那么这些职责就会相互依赖,一个职责的变化可能会影响另一个职责的履行。

开放封闭原则(Open-Closed principle)

软件实体应该是可以扩展的,但是不可修改。

一个类,可以通过添加属性和方法来扩展功能,但是不要修改已经写好的属性和方法。实现开放封闭原则的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。

李氏替换原则(Liskov-Substituion Principle)

子类应当可以替换父类并出现在父类能够出现的任何地方。

依赖倒置原则(Dependecy-Inversion Principle)

抽象不应依赖于细节,细节应该依赖于抽象。

因为人解决问题的思考过程是先抽象后具体,从笼统到细节,所以我们先生产出的势必是抽象程度比较高的实体,而后才是更加细节化的实体。于是,"细节依赖于抽象"就意味着后来的依赖于先前的,这是自然而然的重用之道。而且,抽象的实体代表着笼而统之的认识,人们总是比较容易正确认识它们,而且本身也是不易变的,依赖于它们是安全的。

举例说明:

假设 B 模块需要使用到 A 模块的功能,B 不应当直接使用 A 中的具体类,而应该先定义 A 模块的抽象接口,并由 A 来实现抽象接口,B 只使用抽象接口。这样就达到了依赖倒置的目的,B 也解除了对 A 的依赖。反过来, 假设 A 模块也需要使用到 B 模块的功能,那么 A 也应该依赖于 B 定义的抽象接口。如果模块之间彼此直接依赖对方的实现类,就会造成循环依赖,而依赖倒置可以避免这个问题。

接口隔离原则(Interface-Segregation Principle)

客户端不应该强行依赖它不需要的接口,类间的依赖关系应该建立在最小的接口上。

接口中的方法应该尽量少,不要有很多不相关的方法。这样可以在需求变化的时候,把接口的改动对接口调用者之间的影响控制在一个较低的范围。

接口隔离原则类似于单一职责原则,单一职责原则主要针对的是类与方法,而接口隔离原则针对的是接口。