前言
面向对象是java编程中比较难的一个章节,它与常规的思维方式有差异,学习的过程中需要多多联系生活实际来学习,首先体会两句名言:
l 编码源于生活
l 技术解决问题
面向逻辑思想
面向逻辑思想指的是,将各种编程问题转变成为量和语句来实现,是最基本的编程思维,这里面向可以理解成为使用的的意思,逻辑指的就是 数据 和 语句
l 我们看一个实例:
小时候我们都听过一个笑话,把大象放进冰箱需要分3步,首先 打开冰箱门,然后 把大象放进去, 最后 在关上冰箱门,这种简单的事件使用面向逻辑去实现就是:
数据部分:大象 String
语句部分:使用输出语句即可
这是一个简单的事件,单一看这个事件这种编码是完美的,但是我们知道冰箱不是放大象的,那如果要把其他东西也放进冰箱呢,代码实例如下:
l 大家是否有发现上文中出现的问题
冗余(rong yu),意思就是重复,这类问题我们称为纵向代码冗余,即在编程过程中如果出现某一个事件重复的需要实现,那么单纯的使用面向逻辑去完成就一定会有重复问题,也许3次重复复制黏贴可以解决,那如果100次1万次重复,简单的程序却因为代码重复而占据了大量的篇幅
面向过程思想
为了解决上文中出现的纵向代码冗余问题,这里介绍面向过程思想,面向过程的过程指的是函数(就是方法 以后在java中统称为方法),也就是说面向过程思想提倡编程单位是方法而不是逻辑(量 和 语句)
l 使用面向过程思想解决纵向冗余问题
先写一个程序片段:
在main方法中这样操作:
运行效果 和 之前的一样,上述代码可以看出,我们可以调用一个程序片段
方法的定义
方法指的是一系列的语句集合,可以通过方法名调用方法,就等于运行了方法中的语句
l 方法定义标准语法
返回值类型 + 方法名 + 形式参数 + 方法体
例如: int getInt(char c){ // TODO }
l 返回值类型
返回值类型指的方法运行之后给出的结果 配合 return 语句使用
(注意:是返回值类型)
l 方法名
方法名是方法的引用,方法命名规则需要驼峰式小写,而且要对于方法的功能做一个描述
l 形式参数
形式参数指的是方法中需要处理的变量,可以缺省,但是()一定要写
l 方法体
方法体指的是,方法中的语句集合,可以缺省,但是{}一定要写
方法定义的原则
方法在《数据结构》中被称为算法,我们在写方法的时候必须要遵循以下几个规则:
l 输入 与 输出:方法可以没有输入,但是必须有输出,如果没有需定义void
l 准确性:方法的语句必须与方法的命名相吻合
l 可行性:方法中的语句可执行不能报错
l 有穷性:方法中不能进入死循环,或者没有方法出口
多种方法定义举例
l 没有输入 没有输出
没有返回值的方法需要是 void 表示返回值类型
l 有输入 没有输出
l 没有输入 有输出
有返回值类型的方法必须使用 return 返回具体数据
l 有输入 有输出
l 一些其他方法
l 小结:上文中的代码我们可以看到 方法就是语句的集合,将一些重复出现的语句写在方法中可以解决纵向代码冗余问题
(解析: public static 表示方法的使用权限,是面向对象的内容,这里理解为固定代码)
方法的调用
方法定义好之后是不会自动运行的,需要被调用,只有标准的 main 方法才是会被jvm自动调用运行的,是程序的入口,所以需要mian中调用方法
l 直接使用方法名字调用方法
代码实例:
方法的嵌套
方法和语句一样可以在方法中调用其他方法
retrun 关键字
return关键字可以结束方法并且返回返回值,如果是引用类型的返回值可以返回null
(注意:有时候合理的使用return可以让方法有多个出口)
方法的传值问题
l 形式参数(形参)
方法在定义时括号内的参数内容就是形式参数,形式参数类似于一个变量,java中形式参数在使用时必须被赋值
图中的 i,j,k 是形式参数
l 实际参数(实参)
实际参数是指在方法调用时传入给方法的具体值,在调用的时候完成参数赋值
方法调用时 5,6,“77”为实际参数,对应就是形式参数的类型
l 也可以定义以后在传值
(注意:此时的传值是值拷贝,并不是真实的i)
练习
l 需求,使用面向过程思想,设计实现一个程序,让用户输入3个数,输出最大的数
l 需求,使用面向过程思想,设计实现一个程序,系统给定一个数组{1,2,3,5,9,8}输出最小值,最大值,平均值,累加和,从小到大排序
l 需求,使用面向过程思想,设计实现一个计算器要求能够计算 10以内的算式问题,例如:1+2+3+4 得数 10
l 需求,使用面向过程,改造自动改卷系统
小结
面向过程思想能够解决面向逻辑思想的纵向代码冗余问题,因为编程单位从 量 和 语句 转变成方法,面向过程思想要求把可能重复出现的语句或者数据定义在文件的头部,下文只需要通过方法名调用,即 面向过程的核心 方法调用
面向对象思想
对于单个文件的编程,面向过程思想已经足够优秀,封装的概念崭露头角,让我们以语句整体的角度和调用的角度去思考问题,在编程前就实现定义方法,但是如果对于多个文件,面向过程又开始暴露出新的问题
l 面向过程存在的问题
上文中我们以大象放进冰箱开始阐述了纵向代码冗余问题,如果现在我们新建一个文件,Part08.java 这个文件需要做的事也是把大象放进冰箱,如下图所示:
l 报错原因显而易见:方法未定义,我们解决这个错误,如下图:
l 虽然问题被解决,但是这个方法我们之前写过了,我们将之前的代码文件并列对比
l 我们可以看到,将两个文件 Part03 和 Part08 横向对比依然出现重复
横向代码冗余,我们使用面向过程思想编程,要求事先将方法定义在文件头部,如果方法需要重复使用那么在多个文件的头部就需要重复定义方法,解决这类问题使用面向对象思想
类的认识
面向对象思想,指的是 考虑整个工程或者整个项目,把数据和方法按照用途进行分类,事先写在一个代码类文件中(后续我们都称为类),在主程序方法中通过类名去访问对应的数据和方法的思想
l 什么是类
在面向对象思想中类是 一系列代码的归集
l 使用面向对象思想解决上文中的问题
(注意:我们可以清楚的看到,在代码类文件中没有main方法,通过类名方法)
练习
尝试使用面向对象思想,完成计算器程序的改造
包
通过练习我们发现,按照面向对象思想 类是一些列代码的归集,我们把一些功能相似的方法放在一起称作类,我们把类放在一起称作包
l 包是类的文件夹,它的作用就是帮我们规范的整理类
l package 包,包包,包包是女生的通用货币,装东西,谈判,祈求原谅
创建包
l 包的命名
域名倒置的原则,其实本质上只要不和其他人重复就可以,最后一段为包的用途
面向对象特性 之 封装
封装指的是将相同相似的数据或者方法放在一个类中,是面向对象最基础的思想之一
例如:我们在完成一个计算机的程序,会有用户输入数据的方法 会有数据运算的方法,根据封装思想应该分成两个类 一个负责获取输入 一个负责运算
访问控制符
代码进行分包,分类之后,java中为了安全,提供了4种访问控制符
l private : 私有的 出了类就不能在访问
l 缺省(就是不写控制符):跨包就不能访问
l public : 公共的 都可以访问
l protected :(以后再说)
Java中的封装
java编程中封装会将属性部分私有化,方法公开化
l 从编程角度考虑为了提高代码的整体性(黑盒效果),安全性
l 从生活的角度,考虑事物的宏观概念,和关注层面
代码举例:
(注意:当下对于封装的理解可以当做规定)
面向对象特性 之 抽象
类是一系列算法的归集,在编程中通过类名 点的方式 调用方法,给一个类合理的命名就是抽象,抽象就是起名字
l 合理命名
望文生意,要求看到类的名字就能联想到里面的属性和方法
驼峰式大写,要求每个单词首字母大写
(注意:起名字是个难点,有很多的规矩以后再提)
对象的认识
我们已经了解到,面向对象思想中是以类为单位,类是一些列代码的归集,那为什么不叫面向类编程而叫面向对象编程,下面我们来认识一个问题
l 妲己 秒杀 鲁班
王者荣耀中妲己常规连招闪现231,鲁班也有对应的技能,我们使用代码描述:
首先我们把妲己的相关信息归集在一起,有:
然后把鲁班的相关信息归集在一起,有:
最后在主函数调用:
代码好像很相似,就因为他们的属性不一样我们就要设计两个类吗?显然不是的,类除了有行为还有属性
构造器的认识
类是一系列代码的归集,行为部分就是方法,数据部分就是属性,上文中 妲己 和 鲁班的行为是一致的,数据是不同的,我们就做了两个类,这明显是不合理的
l 生活中的面向对象
编码源于生活,生活中我们会说“万事万物皆对象”,意思就是 任何事物宏观存在我们就说它是一个对象(东西),我们会把很多相似的东西用一个类别去称呼(抽象),比如我们看到一台苹果,一台华为,一台小米 我们统称为手机,看到福建人,广东人,台湾人 我们统称中国人,而后我们如果单独谈论到手机,其实它是一个抽象的名词,我们就会联想到具体的有屏幕,插孔,键盘等实际的东西,就会联想到打电话发信息等功能
(结论:生活中我们是先看到对象认识对象,才能抽象成类 即 先有对象才有类)
l 编码中的面向对象
在编码的时间则相反,我们是先有类才有对象,我们先讲数据和方法写在类文件中,行为可能一致,但是数据会有不同,就类似于上文中的 妲己 和 鲁班,也就是说 我们其实不应该给类的数据部分赋值
英雄类
解决上述问题有如下代码:
l 代码解析:
Hero 类名,表示抽象,望文生义,首字母大写
private String name; 属性部分private 表示封装,属性私有化
没有static 后续再谈,static表示共享
构造器部分,也称为构造方法,形态和方法类似,public 表示公开,方法名必须和类名相同,运行的结果不需要返回值,一定会获得一个对象
l 构造器的使用
new 关键字调用构造器,传入实参,给类的属性赋值,获得一个对象
(小结:对象也是一个类,也是一系列代码的归集,只不过它是将类的数据部分赋值完之后的结果)
关键字 static this
l static 关键字表示静态,可以修饰属性和方法,表示共享的,如果在一个类中,所有对象的属性都是同一个值,那么它可以是static
l this 关键字表示对象自己,可以用来调用属性和方法,一般使用在构造器中,如果构造器的入参和属性重名,那么会使用它来区别哪一个是类属性哪一个是入参属性
正确认识类
面向对象中一系列代码的归集表示类,类的数据被个性化表示对象(实例),static声明的属性方法叫静态属性类属性全局属性,静态方法类方法全局方法,可以通过类名调用,其他我们称为实例方法普通方法
l 类的组成部分
权限 class 类名{ 类体 }
类体常规包括:属性部分 方法部分 构造器部分
正确认识构造器
l 构造器的作用:实例化
l 构造器的命名:必须和类名一致
l 构造器的基本格式:权限+类名+形参+方法体
l 构造器的特点:没有返回值,但是运行完构造器能获得一个对象
l 构造器的重载
1、全属性构造器:
2、部分属性构造器
3、空属性构造器
l 注意点1:如果没有写构造器JDK赠送一个无参构造器
l 注意点2:如果写了构造器JDK就不赠送无参构造器
get/set方法
在企业中因为代码需要可维护,可重用,可拓展所以一般会不写构造器,使用无参构造器,构造出一个空对象,使用get/set方法赋值
练习
l 画出从面向逻辑到面向对象的推理图
l 写一个用户类
l 使用面向对象思想改造改卷系统
小结
l 面向对象解决纵向冗余问题,核心在于类的引用调用
l 面向对象的特性:封装 抽象 继承 多态
l 创建类关键字 class 类的命名要望文生义,首字母必须大写
l 类的结构有 属性部分 方法部分 构造器部分
l 对象是一个特殊的类,将数据赋值后
l 权限整理成表格:
|
|
private |
缺省 |
protected |
public |
|
本类 |
可见 |
可见 |
可见 |
可见 |
|
同包不同类 |
不可见 |
可见 |
可见 |
可见 |
|
跨包继承 |
不可见 |
不可见 |
可见 |
可见 |
|
跨包非继承 |
不可见 |
不可见 |
不可见 |
可见 |