0基础java入门:第二十五节.面向对象思想理解思路。(本章需要时间和代码积累才能理解通透 不要着急 先来了解 敲上三年代码再回来看)
面向对象是现在大部分编程语言中都会提及和使用到的一种思想方式。有人说很难理解,但个人觉得其实不难。因为面向对象本身是更贴近现实生活的思考方式。比如,当我们想要一辆汽车,首先想到的是找到一个卖车的商店。这里的商店就是一个对象,这个商店对象的功能就是售卖汽车。通过商店可以获得汽车。这种思考方式的核心是什么我们在之后的内容中逐步分析。
面向对象与面向过程
首先我们先来了解以下编程思想中的面向过程和面向对象两种方式的不同。
面向过程 : (Procedure Oriented)是一种以过程为中心的编程思想。以步骤未核心考虑先后执行顺序,完成某一件事情。如果某些步骤发生问题,可能需要重新开始。
面向对象 : (Object Oriented) 是一种以对象未中心的编程思想。以某个对象的某个功能能帮我完成什么事情为核心,思考如何完成一件事情。如果对象出现问题可以考虑更换对象。
以上的概念是自己理解的。单个人认为这就是面向对象和面向过程的核心思想。比较抽象,下面举例说明。
比如我饿了 ,想吃一桶泡面:
面向过程思考:首先需要 买泡面 --> 需要搞到开水 -->泡面-->等待-->吃泡面。
这时关键步骤 比如在等待期间 我的猫 不小心把 面 打翻了,我如果还想吃 需要从头再来一边。
面向对象思考:首先思考 找到可以提供 泡好的面的服务的对象。如 饭店 或者下铺的兄弟。让他去帮我泡一个面。
这时如果对象出现了问题 比如饭店 没有泡面了 我们还想吃 可以考虑换一家饭店。
通过上边的例子我们可以简单体会一下 ,面向对象和面向过程思考方式的不同。但是注意思想没有高低好坏之分。并且面向对象和面向过程是不可分离的。我们不能说一个程序都只是面向对象或都只是面向过程的。面向对象可以使我们在处理和思考业务的时候变得更简单。但是面向对象其实也是基于面向过程的。比如我们在例子中 找到了提供泡面的对象,之后只是我们不考虑泡面的步骤了,但是饭店还是需要考虑这个步骤的,这个步骤是依然存在的。
类与对象的关系
两个简单的概念 ,更抽象向。
类 : 是对具有相同特性事物的抽象描述。(可以描述拥有是那些特性 但是不能具体)
简单解释一下类 :比如 人类 就是一个类 ,人类描述了我们所有的人,并且我们都有一些相同的特性。比如人都有 姓名 年龄 身高 体重 等信息。
比如 汽车类 也是一个类 , 汽车类描述了所有汽车。 比如 汽车都有品牌 颜色 ,排量 ,轴距 等信息。拥有移动 加速 停车 等功能。
对象: 是符合类特性的具体事物。(可以描述 特性的具体值)
简单解释一下对象 :比如 人类中的一个对象 我的同事 王小明 。他的 身高 180 体重 70公斤 年龄 36岁
比如 汽车类的一个对象 王小明的车子 。是一台 白色 宝马 排量2.0 轴距1.7米 可以 移动 家属 和停车。
注意 : 这里一定不要进入一个误区 男人 女人 不是对象 还是类 。可以认为是人类中的两个子类。男人和女人的信息是不能具体的。
通过上边的解释,可以了解类和对象的关系是相互衍生的。当拥有共同特性的多个事物在一起是统称为类。而这类中的具体一个事物就叫做对象。一个类中是可以拥有多个对象的,并且每一个对象都是相互独立的。可以这样理解,人类中包含了你 我 她 以及你的家人和同事,如果我改了名字对其他人是没有影响的。
如何描述一个类
在程序中我们是需要先描述类,之后通过类生成对象的。那么我们怎么描述一个类呢?描述一个类主要描述它的两个方面,第一方面静态的属性,第二方面动态的功能或动作。静态属性理解为可以用一个值表示的特性。动态的功能和动作可以理解为一个复杂的过程,不能用一个值来表示。
比如: 老师类
属性 : 姓名 教龄 性别 职务 等... ...
功能 : 讲课 检查作业 等... ...
上边老师类的 属性中 姓名=张三 性别 = 男 职位=金牌讲师 教龄 = 6年 这些是可以用一个值表示的 属性。
而 讲课 检查作业等是一系列给动作 不能用简单的值表示。是一个功能。
在代码中我们 的属性用 成员变量 表示 ,功能用成员方法表示;
代码演示:
package com.test.demo;
// 这个类 用来描述 老师类 不需要主函数执行
public class Teacher {
// 成员变量
String name; // 老师姓名
int year;// 教龄
boolean sex;// 性别
String post;// 职务
// 成员方法
public void tock(){
System.out.println("老师在讲课");
}
public void check(){
System.out.println("老师在检查作业");
}
}
以上实在代码中如何表示一个类的特性。后边我们会反复使用到的。
类与对象在程序中的用途
类的做用主要是用来描述我们业务中需要处理的信息样式和功能的标准。对象是用来具体存储信息和执行功能的。当然我们并不是毫无目的的将所有的类属性都描述出来,只需要描述业务中我们需要处理的和使用的特性就可以。比如老师 也是有身高 体重等特性,和吃饭 睡觉等方法的,但是我们在业务中对这些特性么有使用和处理也就不需要描述了。
以下内容 适当阅读,如果不理解,可以先记下 三大特点和五大基本原则大概是说明就可以。
内容转载于 :风之之
网址:https://www.cnblogs.com/fzz9/p/8973315.html#%E3%80%80%E3%80%801%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3%E5%8E%9F%E5%88%99srp
面向对象的特性
面向对象的三大特点 : 封装 继承 多态。
封装:
封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。
封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员。
面相对象的不就是使用程序处理事情时以对象为中心去分析吗,与面向过程不同,面向过程关心处理的逻辑、流程等问题,而不关心事件主体。而面向对象即面向主体,所以我们在解决问题时应该先进行对象的封装(对象是封装类的实例,比如张三是人,人是一个封装类,张三只是对象中的一个实例、一个对象)。比如我们日常生活中的小兔子、小绵羊都可以封装为一个类。
![](https://img-blog.csdnimg.cn/20210308171415347.jpeg)
比如兔子的属性有两只耳朵、四只腿、一双眼睛、三瓣嘴等;行为(功能)有跑、跳、吃素等。
继承:
继承是面向对象的基本特征之一,继承机制允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。类似下面这个图:
![](https://img-blog.csdnimg.cn/img_convert/c3a068d77cd5972081b42be1b05594db.png)
我们在上面已经封装了兔子这个类,其他动物也一样可以进行封装。在封装过程中我们发现兔子、绵羊这两个类具有相似的功能或特性如吃草,所以我们可以抽取共有特征和方法形成高一层的类,如这里的食草动物、食肉动物。继承之间是子父类的关系。继承机制可以很好的描述一个类的生态,也提高了代码复用率,在Java中的Object类是所有类的超类,常称作上帝类。
多态:
多态同一个行为具有多个不同表现形式或形态的能力。是指一个类实例(对象)的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
多态的优点:
- 1. 消除类型之间的耦合关系
- 2. 可替换性
- 3. 可扩充性
- 4. 接口性
- 5. 灵活性
- 6. 简化性
多态存在的三个必要条件:
- 继承
- 重写(子类继承父类后对父类方法进行重新定义)
- 父类引用指向子类对象
简言之,多态其实是在继承的基础上的。比如说今天我们要去动物园参观动物,那么你说我们去参观兔子、参观绵羊、参观狮子、参观豹子都是对的,但你不能说我们去参观汽车。在这个例子中,子类具有多态性:除了使用自己的身份,还能充当父类。
五大基本原则
面向对象的五大基本原则:单一职责原则(SRP),开放封闭原则(OCP),里氏替换原则(LSP),依赖倒置原则(DIP),接口隔离原则(ISP)
1、单一职责原则(SRP)
一个类应该有且只有一个去改变它的理由,这意味着一个类应该只有一项工作。
比如在职员类里,将工程师、销售人员、销售经理这些情况都放在职员类里考虑,其结果将会非常混乱,在这个假设下,职员类里的每个方法都要if else判断是哪种情况,从类结构上来说将会十分臃肿。
2、开放封闭原则(OCP)
对象或实体应该对扩展开放,对修改封闭。
更改封闭即是在我们对模块进行扩展时,勿需对源有程序代码和DLL进行修改或重新编译文件!这个原则对我们在设计类的时候很有帮助,坚持这个原则就必须尽量考虑接口封装,抽象机制和多态技术!
3、里氏替换原则(LSP)
在对象 x 为类型 T 时 q(x) 成立,那么当 S 是 T 的子类时,对象 y 为类型 S 时 q(y) 也应成立。(即对父类的调用同样适用于子类)
4、依赖倒置原则(DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。具体实现应该依赖于抽象,而不是抽象依赖于实现。
可以这样理解,上面我举例子的时候先说了兔子和绵羊,然后才推出食草动物。但如果我们继续认识了牛、马等食草动物,我们会发现我们需要不断调整食草动物的描述,这样程序会变得僵化,所以我们不应该让子类依赖于实体,不应该让父类模块依赖于子类模块。所以我们需要将食草动物设计为抽象类,即抽象类或接口。这样下层只需要实现相应的细节而不会影响父类。
5、接口隔离原则(ISP)
不应强迫客户端实现一个它用不上的接口,或是说客户端不应该被迫依赖它们不使用的方法,使用多个专门的接口比使用单个接口要好的多!
比如,为了减少接口的定义,将许多类似的方法都放在一个接口中,最后会发现,维护和实现接口的时候花了太多精力,而接口所定义的操作相当于对客户端的一种承诺,这种承诺当然是越少越好,越精练越好,过多的承诺带来的就是你的大量精力和时间去维护!
这些基本原则需要我们在使用面向对象编程中慢慢领会、总结。