OOP
我们都知道Java是面向对象的语言,那么什么是面向对象呢?面向过程编程相对来说,比较好理解。
面向过程编程是一种以过程为中心的编程方式,其中程序由一系列函数或子程序组成,这些函数执行特定的任务。它强调的是“做什么”,即程序的行为和操作。简单来说,我们编程的时候是编写一个个函数,来解决问题。而且这个思维过程是自顶向下,而且需要我们设计的时候就要考虑好函数之间的调用关系。
抽象
所有编程语言的最终目的都是为了提供一种抽象方法。或者说,解决问题的复杂度直接取决于抽象的种类与质量。这个有点像数学建模,好的抽象,就像好的数学模型,能够很好 地解决现实中的问题。而好的数学建模就需要我们抽象出一些核心的东西,这个抽象过程往往是比较复杂,非常考验我们的能力。
从这样的角度来说,汇编语言是对机器码的抽象;后序面向过程的高级语言又是进一步对汇编语言的抽象。而每一种高级语言观察问题的角度或者说着重解决的问题不同,带来了很多种高级语言,每一种高级语言在其侧重的领域有比较大的优势,但是在其不擅长的领域往往就很难用。
面向对象则通过抽象出一个对象,每个对象都有自己的状态,提供一些对外的方法。
** 面向对象设计方法特征**
- 所有的东西都是对象;
- 程序是一大堆对象的组合,对象之间通过消息传递信息
- 对象可以封装已存在的对象
- 每个对象都有一种类型,类型意味着我们能发什么消息给它,它能接受什么消息,因为不能通信的孤立的对象是没有意义的
- 同一类型能接收相同的消息
对象类型意味着什么
对象类型决定了它对外暴露的方法,这也就意味着当我们拿到一个对象,我们知道它能干什么? 举个现实的例子,当我们看到一辆小汽车,我们就知道它可以驾驶,也可以载人载物。汽车类是一个不存在的实体,小汽车是实例。汽车类决定了它暴露的通用的方法。
权限控制
继续用我们上面的例子。汽车这个类的定义,在我们生活中是由汽车行业共同约定的规则构建的。我们驾驶汽车的过程种不关系,发动机是怎么运行的;汽车厂也不希望,我们打开发动机做改动(因为这是不安全的);这相当与汽车怎么运行的是对我们隐藏起来的;我们只需要关系怎么开车就可以。
那么在面向对象的设计,怎么实现这种效果呢。答案是采用权限控制。
- public 开放给外部使用
- private 私有的
- protected 包一级别的权限控制
如何复用代码
面向对象的很大的一个优势就是采用了组合与继承的方式更好地复用代码,减少代码量。
组合
我们创建一个类,肯定是希望能够复用这个类的代码。最简单地方法就是直接使用这个类地对象;也可以将这个类地对象置入一个新的类。这种方式称之为组合,是一种包含关系。
我们新建类地时候,首先考虑地就是组合对象,而不是继承;继承会增加复杂程度。组合的话更加灵活。
补充一点,对象的组合的时候,成员对象一般设置为私有。这样新类的客户端程序就不能直接访问成员变量(就像普通驾驶员不需要访问发动机一样)。这样带来的好处就是:
我们更换发动机的时候客户端时不感知的,这样可以增加灵活性。
继承
我们通过创建对象,把各种各样的数据与功能封装到一个对象里面;如果发现我们建好了一个数据类型,需要一个与这个差不多功能的数据类型,如果能够复用代码那是再好不过的了。
用组合实现上面说的可以吗
功能上可以,但是会有很大的问题。
public class Person {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Person() {
}
}
public class Man {
private String sex;
private Person person;
public String getName() {
return person.getName();
}
public void setName(String name) {
person.setName(name);
}
public String getAge() {
return person.getAge();
}
public void setAge(String age) {
person.setAge(age);
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Man() {
}
}
你发现了什么? 如果采用组合的方式实现的话,所有的方法还都得写一遍。
你也许会说,那把Person改成public不就可以不写这些方法了吗
改成public会破坏封装,这样的话使用这个类的还要考虑这个类的内部的具体实现。这样肯定是不合适的。
所以Java里面通过extends关键字,实现继承,继承相当于新建一个类,但是这个新的类不仅仅包含现有的成员变量,还包含extends的base类的所有成员与暴露的接口。
另外补充一点,继承的关系是 is - a 的关系。组合的关系是has - a的关系。
面向对象与面向过程对比
总结
面向过程编程和面向对象编程各有优劣,适用于不同类型的应用场景。对于小型、简单的任务,面向过程编程可能是更直接的选择;而对于大型、复杂的系统,尤其是那些需要良好的维护性和扩展性的项目,面向对象编程提供了更强大的工具和支持。在实际开发中,很多现代编程语言都支持多种编程范式,开发者可以根据具体需求选择最合适的风格或混合使用。