【作者前言】:13年入圈,分享些本人工作中遇到的点点滴滴那些事儿,17年刚开始写博客,高手勿喷!以分享交流为主,欢迎各路豪杰点评改进!
[1]
🔥知识点内容
🔓1. 编程思想 [2]
面向过程、 面向对象
自我理解层面:
面向过程
:将一个任务进行拆分,拆分成不同的步骤,然后按照步骤一步步的执行,完成功能
面向对象
:找对象,对象之间如何配合,完成功能
eg:
去上海旅游,你们怎么去?
面向对象
:高铁、飞机 找一个事物,能够帮助我们运输过去
面向过程
:自驾到天津-河北-山东-江苏-上海,一直细化到出门左转几米,然后再右转
对象
:一切客观存在的事物都是对象,万物皆对象;
类
:是对象共性的抽象;是创建对象的模板
官方标准层面:
面向对象程序设计
:将数据及对数据的操作封装在一起,成为一个不可分割的整体,同时将具有相同特征的对象抽象成一种新的数据类型 --- 类
通过对象间消息传递使整个系统运转,通过类的继承实现代码重用
image.png
面向对象的编程思想,使设计程序 编写程序的过程清晰化,有利于将程序模块化,可以组织比较大的团队开发程序,按模块进行分工
所谓面向对象的方法学,就是使我们分析、设计和实现一个系统的方法,尽可能地接近我们认识一个系统的方法。包括:
面向对象的分析(OOA,Object-Oriented Analysis)
面向对象的设计(OOD,Object-Oriented Design)
面向对象的编程(Object Oriented Programming) 以...为向导的编程
🔓2.抽象 [3]
面向对象中的抽象是把系统中需要处理的数据和这些数据上的操作结合在一起,根据功能、性质、作用等因素组成不通的数据类型。
抽象数据类型是进一步设计、编程的基础和依据
。
在面向对象的程序设计中,抽象数据类型是用"类"
来代表的
🔓3.Java语言特点 [4]
Java具备描述对象以及对象之间关系的能力,因此是
面向对象的编程语言
。
Java语言的设计集中于对象及其接口
,它提供了简单的类机制以及动态的接口模型
。
对象中封装
了状态变量以及相应的方法
,实现了模块化和信息隐藏;
类则提供了一类对象的原型,并且通过继承机制
,子类可以使用父类所提供的方法,实现了代码的复用
。
面向对象最重要的三大特征是:封装、继承、多态
。
🔓4.类和对象的说明 [5]
如果没有事先准备好的特征描述表,那么目击者就无法准确描述出嫌疑人的特征,而没有属性值的特征描述表是无法帮助警察找到嫌疑人的,因此可以看出:
在Java中万事万物皆对象
事实上,Java离完全的面向对象编程语言还有最后的一小步距离,因为Java中存在基本数据类型,而后续以Java为目标的语言如C#则真正实现了万物皆对象,Java用包装类型来应对
对象依赖于类存在(模板-个体实例)
在程序中应该使用的是对象
分析过程先有对象后有类;开发过程先有类后有对象
在之前的编码过程中我们已经看到:用Java编写的所有代码都位于某一个类的内部
标准的Java库提供了几千个类,可以用于日期、日历、网络、IO等程序设计
我们需要在Java程序中创建一些自己的类
,以便描述应用程序中所对应的问题领域中的对象
面向对象的一个原则会让用户自定义类变得轻而易举:可以通过扩展一个类来建立另一个新的类
事实上,Java中所有的类都源自一个“神通广大的超类”:Object,以后会对该类进行详细介绍
在扩展
一个已有的类
时,这个扩展后的新类具有所扩展的类的全部属性和方法
,在新类中只需提供适用于这个新类的新方法和数据
即可,这称为继承
,后续将会继续详细介绍
🔓5. 类的基本构成元素 [6]
类是描述对象的“基本原型”,它定义一种对象所能拥有的数据和能完成的操作,在面向对象的程序设计中,类是程序的基本单元,
最基本的类由一组结构化的数据和在其上的一组操作构成
:一个更完整的类结构:
image.png
🔓6. 对象 [7]
类是同等对象的
集合与抽象
。它是一块创建现实对象的模板
。对象
是类的实例
,对象是面向对象编程的核心部分,是实际存在的具体实体,具有明确定义的状态和行为
在程序中发挥对象的功效,需要了解对象的三个主要特征
:
对象的行为
:可以对对象施加哪些操作,或可以对对象施加哪些方法
对象的状态
:当施加那些方法时,对象如何响应
对象的标识
:如何辨别具有相同行为与状态的不同对象
同一个类的所有对像实例,由于支持相同的行为而具有家族式的相似性。对象的行为是用可调用的方法定义的。
此外,每个对象都保存着描述当前特征的信息-对象的状态,对象的状态可能会随着时间而发生改变,但这种改变不会是自发的
。对象状态的改变
必须通过调用方法实现
(如果不经过方法调用就可以改变对像状态,只能说明封装性遭到了破坏
)。
🔓7. 封装 [8]
封装是与对象有关的一个重要概念
形式:将数据和行为组合在一起,并对对象的使用者隐藏数据的实现方式
属性由变量表示,属性名称由类的每个对象共享
每个特定的对象都有一组特定的实例属性值,这些值的集合就是这个对象的当前状态,只要向对象发送一个消息,它的状态就有可能发生改变
封装的特性能够让服务提供者把它服务的细节隐藏掉
,你只需要提交请求与传递它需要的参数,它就会给你返回结果,而这个结果是如何产生的,经过了多少复杂运算,经过多少次数据读取,你都不用管,只要它给你结果就好了。
封装使得对代码的修改更加安全和容易,将代码分成了一个个相对独立的单元,对代码访问控制得越严格,日后你对代码修改的自由就越大
eg:只要电话的外部接口(键盘,屏幕,使用方法等)不发生改变,那么不管电话内部电路,技术如何改进,用户都不需要重新学习就可以使用新一代的电话。同样,只要汽车的方向盘,刹车等外部接口不变,那么,不论如何改造它的发动机,用户也一样会驾驶这类汽车
- 明确指出了哪些属性和方法是外部可以访问的。这样当需要调整这个类的代码时,只要保证公有(public:)属性不变,公有方法的参数和返回值类型不变,那么就可以尽情的修改这个类,而不会影响到程序的其他部分,或者是使用到这个类的其他程序
能很好的使用别人的类,而不必关心其内部逻辑是如何实现的,让软件协同开发的难度大大降低。
🔓8. 对象状态 [9]
对象的状态并不能完全描述一个对象,每个对象都有一个唯一的身份。例如,在一个订单处理系统中,任何两个订单都存在着不同之处,即使所订购的货物完全相同也是如此。需要注意,作为一个类的实例,每个对象的标识永远是不同的。
一般情况下,对象的标识可以由内存地址确定(在非序列化等情况下),可以依据次确定对象的哈希值
状态常常也存在着差异,对象的这些关键特性在彼此之间相互影响着
🔓9. 类的声明形式 [10]
9.1语法
/*
*[访问权限修饰符][修饰符] class 类名 {
成员列表
}
*/
public native class Person {
String name; // 名字
}
1、可选的类访问权限修饰符限定本类能够被哪些其他的代码访问,包括
public
和default
(内部类有更多选择)以后将会有专门的部分详细介绍
2、可选的修饰符说明当前方法的特性,包括final
、abstract
、native
等,也会有专门的博客对重要修饰符进行详细介绍
3、class
声明类
的关键字,注意大小写
4、需要符合Java标识符的结构要求
一个约定俗成的命名规则:类名的命名规则是首字母大写
,多个单词时,每个单词首字母大写
5、包括成员变量和成员方法
6、类的名字由大写字母开头而单词中的其他字母均为小写
;如果类名称由多个单词组成,则每个单词的首字母均应为大写
,把这些单词连接在一起,即不要使用下划线分割单词,例如:OrderList
7、如果类名称中包含单词缩写
,则这个所写词的每个字母均应大写
,如:XMLExample
8、由于类是设计用来代表对象的,所以在命名类时应尽量选择名词
。 如上例的: Bike
9.2成员变量
成员变量是类中的特有属性变量
在类中声明成员变量的格式
【变量修饰字】 变量数据类型 变量名1,变量名2【=变量初值】;
...
成员变量的类型可以是Java中任意的数据类型
,包括基本类型,类,接口,数组等
普通的成员属性取值在该类的不同对象中不能被共享
image.png
Java中每个类型都有固定的初始值
,如int的初始值是0,具体类型的初始值可以回顾学习数据类型时的内容
在类中定义的成员变量可以不用显示初始化为其提供取值即可使用,这时候成员变量的值为其类型的初始值
不管在任何地方,引用类型都需要初始化后才可使用
,因为引用类型的初始值为null,代表不具备存储数据的内存空间,直接使用会造成程序运行异常
🔓10. 对象创建 [11]
对象是典型的引用数据类型,因此和数组相似,初始化时需要
使用new运算符
从堆中分配内存,步骤是:说明新建对象所属的类名
说明新建对象的名字
用new为新建对象开辟内存空间
- 创建对象的一般语法是:
类名 引用名 = new 类名();
使用已经定义好的类,创建该类对象的过程称为“实例化”
new是“为新建对象开辟内存空间”的运算符
;它以类为模板,开辟空间并实例化一个对象,返回对该对象的一个引用(即该对象所在的内存地址)
🔓11. 作用域 [12]
正如之前的博客中所说,Java中,变量作用域
由花括号的位置
决定
通过new构建的Java对象不具备和基本类型一样的生命周期。当用new创建一个Java对象时,它可以存活于作用域之外。
所以编写用代码:
{
String companyName=new String(“chinasofti”);
}
引用companyName在作用域终点就消失了,然而
, companyName指向的String对象仍继续占据内存空间。在这一小段代码中,无法在这个作用域之后访问这个对象,因为对它唯一的引用已超出了作用域的范围,在后继章节中,我们将会看到在程序执行过程中,怎样传递和复制对象引用。
???思考???:由new创建的对象,只要需要,就会一直保留下去。如果Java让对象继续存在,那么靠什么才能防止这些对象填满内存空间,进而阻塞你的程序呢?
答:
Java有一个垃圾回收器
,用来监视用new创建的所有对象
,并辨别那些不会再被引用的对象。随后,释放这些对象的内存空间,以便供其他新的对象使用。也就是说,你根本不必担心内存回收
的问题。你只需要创建对象,一旦不再需要,它们就会自行消失。这样做就消除了这类编程问题(即“内存泄漏”),这是由于程序员忘记释放内存而产生的问题。
需要注意的是,垃圾回收其实并不能完全防止内存泄露
,后续我们将会详细介绍垃圾回收机制并说明可能会导致Java内存泄露的情况
🔓12. 如何访问成员? [13]
java中实例化类的对象之后,就可以访问到类中的成员
使用成员运算符(.
)来访问成员,一般语法是:对象名.成员名
例如:student.age=18;
🔓13. 成员方法 [14]
13.1 概念
成员方法是类中进行数据处理,实现相关功能的函数
13.2 语法
方法决定了一个对象能够接收什么样的消息。方法的基本组成部分包括:名称、参数、返回值和方法体
。下面是它的基本声明形式:
【访问控制】【方法修饰】 返回类型 方法名称(参数1,参数2,…) {
…(statements;) //方法体:方法的内容
}
返回类型可以是任意的Java数据类型,当一个方法不需要返回值时,返回类型为void
。
image.png
13.3 方法的语法组成部分说明
返回类型
描述的是在调用方法之后计算的结果并告知调用者的值
参数列表
给出了要传给方法的信息的类型和名称
方法名和参数列表
(它们合起来被称为“方法签名
”)唯一地标识出某个方法
Java中的方法只能作为类的一部分来创建
方法
只有通过对象才能被调用
(后续介绍的static方法除外
),且这个对象必须能执行这个方法调用,如果试图在某个对象上调用它并不具备的方法,那么在编译时就会得到一个错误
13.4 方法的特点
定义方法可以将功能代码进行封装。
便于该功能进行复用。
方法只有被调用才会被执行。
方法的出现提高代码的复用性。
方法若没有返回值,则用关键字void表示,那么该方法中的return语句如果在最后一行可以省略不写。
方法中可以调用方法,不可以在方法内部定义方法。
定义方法时,方法的结果应返回给调用者,交由调用者来处理
13.5 方法的参数
1、一个参数 方法名称(数据类型 变量名)
2、多个参数 方法名称(数据类型 变量名1,数据类型 变量名2 ,....)
image.png
image.png
13.6 Return
方法声明中有一个
重要的关键字
---Return
return的用法包括两方面:代表
“已经做完,离开此方法”
如果此方法产生了一个值,这个值要放在return语句后面
- 可以定义方法
返回任意想要的类型
,如果不想返回任何值
,可以指示此方法返回void
(空)
image.png
13.7 定义在方法中的局部变量和类的成员变量之间存在一些差异
image.png
13.8 方法调用
成员方法也使用成员运算符(
.
)来调用
同一个类中的方法在本对象中调用其他方法直接使用方法名(static方法后续探讨)
13.9 方法的命名
方法的名字的
第一个单词
应以小写字母作为开头
,后面的单词
则用大写字母开头
,例如: sendMessge
参数的命名规范和方法的命名规范相同,而且为了避免阅读程序时造成迷惑,应该在尽量保证参数名称为一个单词的情况下使参数的命名尽可能明确
🔓14. 可变API 与 不可变API[15]
在Java中,可供调用的API从
执行后的内存状态的角度
可以从逻辑上划分为两种类型:
可变API
在给定的既有内存上进行操作的API
不可变API
执行时需要新分配一段内存后再执行操作的API
我们看到的new运算符
是一个最典型的不可变API
,因为其功能就是为一个新对象分配新的内存空间
根据可变API和不可变API的逻辑约定,可以发现,Java中的字符串不具备任何的可变API
,因为针对字符串进行的任何改变都是构建了一个新的字符串对象
eg:
String s=”abcd”; s+=”e”; s”abcde” 不是在abcd的原有内容空间上进行添加的,而是创建了一个新的内存空间 存储的”abcde”
🔓15. Java中传递参数的特性 [16]
Java中的参数
只有值传递
传统印象中基本数据类型和字符串传参时是值传递,其他对象传参是引用传递的思想是错误的
基本数据类型 参数传递过程:
image.png引用类型 参数传递过程:
image.png
image.png
🔓16. 形参和实参 [17]
形参
就是一个普通的临时变量
,位置特殊只是为了跳出方法体的作用域以便能够获取实参值
从上面一条可以看出,形参
绝对不是
初学者所理解的占位符
方法体
中的代码操作
的是形参变量
,和实参无关
,只不过由于需要借助于实参的数据值,因此在执行方法第一条语句之前,隐式
按照参数的位置关系
利用实参
对相应位置的形参
进行了赋值操作
由此可以得出一个重要的结论:
当方法中的形参在没有调用不可变API之前,形参的任何改变都将影响实参的状态,而当形参执行了任何不可变API之后,形参和实参之间就断开了这种状态联系
image.png
🔓17. 可变参数 [18]
有过C语言学习经历的同学可能对其中的标准输出函数printf()非常熟悉,这个函数有个特点,提供格式字符串后,根据格式字符串中的占位符,后面可以
根据占位符的个数提供不同的数据变量以供输出
,这种函数的参数称为:可变参数
Java1.5增加了可变参数特性,适用于参数个数不确定,类型确定的情况
Java把可变参数当做数组处理
可变参数必须位于最后一项
。当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持有一个可变参数
。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项
可变参数用...代替标识
, ...位于变量类型和变量名之间,前后有无空格都可以
用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数
eg:
image.png
🔓18. 递归 [19]
在程序设计中,方法直接或者间接调用其自身的方法叫做递归调用,简称递归,其设计方法被应用到很多特殊问题的解决上
递归要点:
每次递归调用都要使问题简单化
当递归达到某种程度后能够的到一个已知解以结束递归调用
eg:
image.png