什么是面向对象
1.面向过程和面向对象
这是我们学习Java的开端,众说周知Java就是一门面向对象程序语言,那么什么是面向对象呢?
面向对象,就是指软件工程的一种编程风格,是众多开发范式的一种,除了面向对象,还有面向过程、指令式编程、函数式编程。
所有开发范式中接触最多的还是面向过程和面向对象两种。
1.1 什么是面向过程
面向过程(Procedure Oriented)是一种以过程为中心的编程思想,是一种自顶而下的编程模式。C语言就一种经典的面向过程编程语言。
简单来说面向过程的开发范式中,就是程序员把问题分成一个个步骤,每个步骤用函数依次实现。
比如:
用洗衣机洗衣服面向过程会将任务拆解成一个个步骤(函数),
1.打开洗衣机;
2.放衣服;
3.放洗衣粉
4.清洗
5.烘干
特点:流程化,明确下一步需要做什么,执行效率高。
问题:重用性低、扩展性差、后期维护难度较大等。
1.2什么是面型对象
面向对象(Object Oriented)的雏形最早出现在1960年的Simula语言中。当时的程序设计领域面临这一种危机:在软硬件环境逐渐复杂的情况下,软件如何得到良好 护?
面向对象程序设计语言在某种程度上通过强调可重复性解决了这一问题。目前流行的面向对象语言主要有Java、C#、C++、Python、Ruby、和PHP等。
简单来说面向对象的开发范式中,就是程序员把问题分成一个个步骤,对每个步骤进行相应的抽象,形成对象,通过不同对象之间的调用,组合解决问题。
比如:
把人和洗衣机分成两个对象:
人:打开洗衣机 放衣服 放洗衣液
洗衣机:清洗 烘干
特点:编写出来的代码的扩展性,可维护性都很高。
2.面向对象的三大基本特征
封装、继承、多态
2.1封装
把客观事物封装成抽象的类,并且可以把自己的数据和方法只让可信任的类或者对象操作,对不可信的类或者对象隐藏信息。
例子
1.Javabean的属性私有,提供getset对外访问,因为属性的赋值或者逻辑只能由Javabean本身决定。为不能由外部胡乱修改
private String name;
public void getName(String name){
return name;
}
public void setName(String naem){
this.name = name;
}
2.orm框架
操作数据库,我们不需要关心链接是如何建立的、sql是如何执行的,只需要引入mybatis,调方法即可。
2.2继承
继承是指:它可以使用现有类的所有功能,并无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的类被称为“子类”或“派生类”,被继承的类这称为“父类”或“基类”。继承过程就是从一般到特殊的过程。
举例:
/**
*父类,矩形
*/
calss Rectangle{
//长度
private int length;
//宽度
private int width;
//设置矩形的长度和宽度
public Rectangle(int length,int width){
this.length = length;
this.width = width;
}
//获得矩形的面积
public int area(){
return this.length*this.width;
}
}
/**
*子类,正方形
*/
class Square extends Rectangle{
//设置正方形边长
public Square(int length){
super(length,length);
}
}
在现实生活中,“正方形”就是“矩形”的特例,或者说正方形是通过矩形派生出来的,这种派生关系在面向对象中可以用继承来表达。
2.3多态
多态,就是指一个类实例的相同方法在不同情形下有不同的表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。
这就是说,针对不同对象的具体操作不同,但通过一个公共的类,它们可以通过相同的方式予以调用。
最常见的多态就是将子类传入父类的参数中,当允许时调用父类方法时,通过传入的子类决定具体的内部结构或行为(父类引用指向子类对象)。
父类类型 变量名 = new 子类对象;
变量名.方法名();
无法调用子类特有的功能
3.面向对象的五大基本原则
面向对象开发范式的最大好处是易用、易扩展、易维护,但是,什么样的代码是易用、易维护的呢?什么衡量标准?
罗布特·C·马丁在21世纪早期提出了SOLID原则,这是五个原则缩写的首字母组合,指面向对象编程和面向对象设计的五个基本原则。
3.1单一职责原则(Single-Responsibility Principle)
单一职责原则核心思想:一个类最好只做一件事,只有一个引起它变化的原因。
单一职责原则可以看作高内聚、低耦合在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。
3.2开放封闭原则(Open-Closed Principle)
开放封闭原则的核心思想:软件实体应该是可扩展且不可修改的。也就是说,对外扩展开放、对修改封闭。
开放封闭原则主要体现在两个方面:
(1)对外扩展开放,意味着当有新的需求或变化时可以对现有代码进行扩展,以适应新的情况。
(2)对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对其进行任何尝试的修改。
实现开放封闭原则的核心思想就是对抽象(如接口、抽象类等)编程,因为抽象相对稳定。让类依赖于固定的抽象,所以修改就是封闭的;而通过面向对象的继承和多态机制,又可以实现对抽象类的继承,通过履写其方法改变固有行为,实现新的扩展方法,所以就是开放的。
“需求总是变化的”,没有不变的软件,所以就需要开放封闭原则来 封闭变化以满足需求,同时还能保持软件内部的封装体系稳定,不被需求所影响。
3.3里氏替换原则(Liskov-Substitution Principle)
里氏替换原则的核心思想:子类必须能够替换其父类。这一思想体现为继承机制的约束规范,只有当子类能够替换基类时,才能保证系统在允许期内识别子类,这是保证继承复用的基础。
在父类和子类的具体行为中,必须严格把握继承层次中的关系和特征,将父类替换为子类,程序不会发生任何变化。同时,这一约束反过来是不成立的,子类能替换父类,但父类不一定能够替换子类。
里氏替换原则主要着眼于对抽象和多态建立在继承的基础上,因此只有遵循里氏替换原则才能保证继承复用是可靠的。
里氏替换原则的实现方法是面向接口编程:将公共部分转抽象为基类接口或抽象类,通过继承的方式,在子类中重写父类的方法,实现新的方式支持同样的职责。
里氏替换原则是关于继承机制的设计原则,若违反了里氏替换原则,则必然违反开放封闭原则。
3.4接口隔离原则(Interface-Segregation Principle)
接口隔离原则的核心思想:使用多个小的专门的接口,而不是使用一个大的总接口。
具体而言,接口隔离原则体现在:接口应该是内聚的,应该避免“胖”接口。一个类对另外一个类的依赖应该建立在最小的接口上,不要强迫依赖不用的方法,这是一种接口污染。
分离接口的手段主要有以下两种:
(1)委托分离,通过增加一个新的接口来委托客户的请求,隔离客户和接口的直接依赖,但是会增加系统的开销。
(2)多重继承分离,通过接口多继承来实现客户的需求,这是较好的方式。
3.5依赖倒置原则(Dependence-Inversion Principle)
依赖倒置原则的核心思想是:程序要依赖于抽象接口,而不是具体的实现。简单来说,就是要对抽象进行编程,不要对实现进行编程。‘
在面向过程开发中,上层依赖与下层,当下层发生重大变化时,上层也要跟着变动,这就会导致模块的复用性降低,大大提高了开发的成本。
面向对象的开发很好的解决了这个问题,通过分离接口与实现,使得类和类、模块和模块之间只依赖于接口,而不依赖于具体的实现类。