本文内容主要记载了我学习Java零基础教程视频的笔记和学习心得,内容主要包括:(1) Java环境的配置;(2) 基础语法:关键字、标识符、字面值、操作符、数据类型等; (3) 核心机制:封装、继承、多态、this关键字、static关键字、final关键字、package/import的使用、访问控制级别的设定等内容。
笔记内容的质量由于个人主观因素参差不齐,仅适合作为引子,复习一下知识点,如果您想全面的了解相关内容,这篇文章不适合您
第一章
1、 The differneces between x86(32) and x64(64)
x86代表32位操作系统,主要用于满足普通用户需求;
x64代表64位操作系统,主要用于高性能计算。
2、软连接和硬链接的区别
软连接:相当于windows快捷方式,图标指向源文件;删除源文件后,图标失效。
硬链接:完全复制一份源文件,并同步更新;删除源文件后,硬链接仍然有效。
3、Software development engineer
计算机包括软件和硬件:
**硬件包括:**鼠标、键盘、CPU、内存条…硬件需要软件驱动才能工作
软件包括:
(1) 系统软件(win10),直接和硬件打交道的; (2) 应用软件
软件开发一般是指使用计算机编程语言完成“应用软件”的开发
4、windows最基本的DOS命令
- exit 退出当前DOS窗口
- cls 清屏
- dir 列出当前目录下所有的子文件/目录
- cd 切换目录的路径
绝对路径:该路径从某磁盘盘符下出发
相对路径:从当前所在路径下作为出发点的路径
- cd … 回到上级路径
-cd \ 回到根路径
- f: 回到某磁盘根目录
5、什么是JDK?
Java开发工具包。做Java开发必须安装的一个包,该工具包需要从官网上进行下载。
Java包括三大板块:
(1) JavaSE(Java Platform, Standard Edition) 标准版
(2) JavaEE(Java Platform, Enterprise Edition) 企业版 (比如B/S架构软件)
(3) JavaME(Java Platform, Micro Edition) 微型版 (比如电饭煲,机顶盒,智能手机)
6、Java语言特性
Java语言特性【开源、免费、跨平台、纯面向对象】
(1) 简单性
相对而言,Java不再支持多继承,C++支持多继承,多继承比较复杂
C++中有指针,Java中屏蔽指针概念
Java语言底层是C++实现的,不是C语言
(2) 面向对象
Java是纯面向对象的,更符合人的思维
(3) 可移植性
什么是可移植性?
Java程序可以做到一次编译,到处运行
可以在windows上运行,不做任何修改也可以运行在Linux中
Windows操作系统内核和Linux的肯定不同,两个操作系统执行指令的方式也不一样。
结论:显然Java程序肯定不能直接和操作系统打交道。因为Java程序只有一份,操作系统执行原理都不相同。
SUN的团队很聪明,他们想了一个办法,让Java程序运行在一台虚拟机当中,这个虚拟的计算机叫做Java虚拟机,(Java Virtual Machine,简称JVM)。Java虚拟机再和底层的操作系统打交道。
(4) 多线程
(5) 健壮性
和自动垃圾回收机制有关,自动垃圾回收机制称为GC机制
Java语言运行过程中产生的垃圾是自动回收的,不需要人关心
(6) 安全性
7、Java的编译与运行
7.1、Java的编译阶段
- 编译阶段主要的任务就是检查Java源程序是否符合Java语法,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LLxzacT2-1649233821654)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225101238321.png)]
7.2、运行阶段
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JbfVLwE0-1649233821656)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225101201041.png)]
* JDK>JRE>JVM 三者之间的关系要搞清楚
JDK是用来编译源程序的, 而编译后的类文件需要在JRE(Java Run Environment,JRE)中运行,其中运行的虚拟机就是JVM。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L3kJCGvL-1649233821656)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225104515055.png)]
8、程序执行的原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B7Waggm0-1649233821657)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225110849004.png)]
9、Java的三种注释
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o2bPdxEN-1649233821658)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225110924510.png)]
10、对HelloWorld.java程序的解释
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N9w3MaQy-1649233821659)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225111227804.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rnvGvkSz-1649233821659)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225111844088.png)]
11、public class 和 class的区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZfUz23fz-1649233821660)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225112500502.png)]
12、第一章小结
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YPVyDunx-1649233821660)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211225112523732.png)]
第二章
1、标识符
1.1、什么是标识符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-12lvICZx-1649233821661)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211227114830983.png)]
1.2、标识符的命名规则
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RTYpgGem-1649233821661)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211227114858159.png)]
1.3、标识符的命名规范
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-waXfXCjY-1649233821662)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211227114922646.png)]
2、关键字
关键字都是小写的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bSiblnk7-1649233821662)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211227115156107.png)]
3、字面值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cMarbWJh-1649233821663)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211227120403729.png)]
4、变量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FEDine3K-1649233821663)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211229120043259.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MGVa1j8v-1649233821664)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211229213445036.png)]
5、数据类型
5.1、基本数据类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMvX72BW-1649233821664)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211229222133903.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lHEtOpNx-1649233821664)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20211231115632656.png)]
5.2、字符编码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AYzyzUbW-1649233821665)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220104143839901.png)]
6、转义字符
常用的转义字符:
\t 制表符
\n 换行符
\“ 普通转义符号
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MuLZb3tS-1649233821666)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220104143942551.png)]
7、整数型字面值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UmXVx1t1-1649233821666)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220104165356677.png)]
8、浮点型字面值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jeIrx8N4-1649233821666)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220104165434735.png)]
9、布尔类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QbhUQdHK-1649233821667)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220104165500474.png)]
10、基本数据类型间的转换规则
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5zs74CrW-1649233821667)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220104165545163.png)]
11、算数运算符
12、关系运算符
13、逻辑运算符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U7szCOZQ-1649233821668)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220105223138619.png)]
14、赋值运算符
注意赋值运算符和扩展的赋值运算符之间的关系!
扩展类的赋值运算符不改变结果类型;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzA86KWh-1649233821668)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220107094549181.png)]
byte x=10;
x=10+5; //编译可以正常通过,x=15
x=x+5;// 编译无法通过,编译阶段只检查语法,int类型向byte类型转换会损失精度
其实这段话我还是暂时不太理解,难道x=10+5不一样是损失精度了吗?目前合理的解释就是**:若仅是字面值赋值给byte,short,char类型的变量时,即使是大容量向小容量转换,也不会出错;** 如果在赋值阶段出现变量,则大容量向小容量转换时则会出错!
15、字符串连接运算符
注意"+"号在字符串中的作用!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DjVgKzi-1649233821669)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220107201607106.png)]
16、三元运算符
a?b:c;
17、控制语句
选择结构:
if, if else
switch
循环结构:
for
while
do while
控制循环语句:
break
continue
17.1、if语句
if语句中最多只会执行一句,且if括号内的值必须为true或者false
17.2、switch语句
(1) switch语句也属于选择结构,也是分支语句;
(2) switch语句的语法结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dfpIjPYv-1649233821669)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220109155508314.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8s4zCj7l-1649233821669)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220109155941774.png)]
switch穿透,switch合并
17.3、for循环
for循环的语法结构和执行过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bAabpDkU-1649233821670)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220109164845891.png)]
17.4、while/do while循环
17.5、break语句
break默认终止最近的循环;下面的语句则不同
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xUwkzwt5-1649233821670)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220109205822973.png)]
17.6、continue语句
continue意味着本次循环体中continue后面的语句不执行,继续执行本次循环体的下一次循环
18、接收用户键盘输入
java.util.Scanner s=new java.util.Scanner(System.in);
int age=s.nextInt();//或者下面一句
String ss=s.next();
19、方法
方法的本质是什么?
(1) 方法是一段独立的代码片段,完成某个特定的功能,可以被重复的调用。
(2) 方法定义在类体当中,一个类体中可以定义多个方法;不能在方法中嵌套定义方法。
(3) 方法体定义的位置没有先后顺序。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4T15H8d8-1649233821671)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220110100651219.png)]
(4) 当方法中有static关键字时,如何调用?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uBGUDHw7-1649233821671)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220111145535254.png)]
(5) return 语句的深入理解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ArEDaogi-1649233821671)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220113210436771.png)]
(6) 方法内存的划分
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HCEHSdB7-1649233821672)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220113211347303.png)]
方法区内存中存放代码片段。
栈内存中分配方法运行的所属空间。方法在调用的瞬间,会给该方法分配内存空间,会在栈中发生压栈动作,方法执行结束之后,会将给该方法分配的栈内存空间全部释放,此时发生弹栈动作。压栈:给该方法分配内存空间;弹栈:释放该方法的内存空间。
局部变量在"方法体内存"中声明,运行阶段在栈中分配内存。
20、方法重载
什么条件满足之后构成了方法重载?
(1) 在同一个类中
(2) 方法名相同
(3) 参数列表不同
数量不同
顺序不同
类型不同
(4) 方法重载和什么有关,和什么无关?
方法重载和方法名和形参类型有关,和返回值类型、修饰符列表无关。
21、方法递归
方法递归太深容易发生栈溢出错误,所以一般不提倡使用递归方式,即使终止条件是正确的。
第三章 面向对象
【Java语言的核心机制,最重要的内容】
面向对象都三大特征:封装、继承、多态
采用面向对象的方式开发一个软件,声明周期当中:【整个生命周期中贯穿使用 OO 面向对象方式】
面向对象的分析:OOA
面向对象的设计:OOD
面向对象的编程:OOP
类–>【实例化】–>对象
对象–>【抽象】–>类
1、对象的创建和使用
通过一个类可以实例化N个对象;
实例化对象的方法:new 类名();
new是java语言当中的一个运算符;
new运算符的作用是创建对象,在JVM堆内存当中开辟新的内存空间;
方法区内存:在类加载的时候,class字节码片段代码会被加载到该内存空间中;
栈内存(局部变量):方法片段在执行的时候,会给该方法分配内存空间,在栈内存中压栈;
堆内存:new的对象在堆内存中存储;
数据类型 默认值
byte,short,int,long 0
float,double 0.0
boolean false
char \u0000
引用数据类型 null
Student stu1=new Student();
new Student()是一个学生对象,stu1是一个局部变量【在栈内存中存储】
**什么是对象?**new运算符在堆内存中开辟的内存空间称为对象。
**什么是引用?**引用是一个变量,只不过这个变量存储了一个java对象的内存地址。
java语言中,不能直接操作堆内存,java没有指针,不像C语言;只能通过“引用”去访问堆内存当中对象内部的实例变量。
访问实例变量的语法格式:
读取数据:引用.变量名;
修改数据:引用.变量名=值;
对象创建和使用时,内存的划分:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WcDupNBV-1649233821673)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220116212238558.png)]
JVM内存管理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OWLACAqf-1649233821673)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220116215102015.png)]
空指针异常的案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yaKBBi2U-1649233821674)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220116215939901.png)]
2、面向对象的封装性
封装的好处:
(1) 操作起来比较简单
(2) 封装之后才会形成真正的“对象”,真正的“独立体”
(3) 封装之后意味着以后这个程序可以重复使用,并且这个事务适应性比较强
(4) 封装之后,对于事务本身,提高了安全性。【安全级别高】
封装的步骤:
1、所有属性私有化,使用private关键字进行修饰,private表示私有的,修饰的所有数据只能在本类中访问;
2、对外提供简单的操作入口,也就是说以后就想要访问age属性,必须经过这些简单的入口进行访问;
– 对外提供两个公开的方法,分别是set方法和get方法
– 想修改age属性,调用set方法
– 想读取age属性,调用get方法
3、set方法的命名规范:
public void setAge(int a){
age=a;
}
4、get方法的命名规范:
public void getAge( ){
return age;
}
需要背会的内容:
(1) setter和getter方法没有 static 关键字
(2) 有static 关键字修饰的方法怎么调用: 类名.方法名(实参);
(3) 没有static关键字修饰的方法怎么调用:引用.方法名(实参);
/*
* 封装的步骤:
* 1、所有属性私有化,使用private关键字进行修饰,private表示私有的,修饰的所有数据只能在本类中访问。
* 2、对外提供简单的操作入口,之后外部程序想要访问age属性时,只能通过这些简单的入口进行访问:
* 对外提供两个公开的方法,分别是set和get方法
*
* 3、set方法的命名规范
* public void set+属性名首字母大写(形参){
* age=a;
* }
* 4、get方法命名规范
* public 返回值类型 get+属性名首字母大写(){
* return age;
* }
*
* 一个属性的访问包括两种形式:
* (1) 读取属性 get
* (2) 修改属性 set
*
* setter和getter方法没有static关键字
* 有static关键字修饰的方法怎么调用:类名.方法名(实参);
* 没有static关键字的方法怎么调用: 引用.方法名(实参);
*
*
* */
public class User {
// 年龄
private int age;
public void setAge(int a){
if (a>150 || a<0){
System.out.println("对不起,您提供的年龄不在合理的区间内!");
return;
}
age=a;// java有就近原则,这里其实并没有给age属性赋值,只是将形参age赋值给了它自己,语法有问题
}
public int getAge(){
return age;
}
}
public class UserTest {
public static void main(String[] args) {
// 创建User对象
User user=new User();
System.out.println("用户的年龄"+ user.getAge());
// 修改
user.setAge(-100);
System.out.println("年龄+"+user.getAge());
}
}
3、构造方法
快捷键:ctrl+/ 功能:快速单行注释/取消注释
快捷键:ctrl+shift+/ 功能:快速多行注释/取消注释
构造方法的使用案例和技巧:
package core03;
public class User {
public User(){
System.out.println("User's default constructor invoke!");
}
public User(int i){
System.out.println("User's default constructor invoke!");
}
}
package core03;
/*
* 关于java类中的构造方法:
* 1、构造方法又被称为构造函数/构造器/Constructor
* 2、构造方法的语法结构:
* 【修饰符列表】 构造方法名(形式参数表){
* 构造方法体;
* }
* 3、回归普通方法的语法结构:
* 【修饰符列表】 返回值类型 方法名(形式参数列表){
* 方法体;
* }
*
* 4、对于构造方法,“返回值类型”不需要指定,并且也不能写void,
* 只要写上void,那么这个方法就成为了普通方法。
*
* 5、对于构造方法来说,构造方法的方法名必须和类名保持一致。
*
* 6、构造方法的作用?
* 构造方法存在的意义是:通过构造方法的调用,可以创建对象。
*
* 7、构造方法应该怎么调用?
* 普通方法调用的技巧:
* 方法修饰符中有static的时候:类名.方法名(实参列表)
* 方法修饰符中无static的时候:引用.方法名(实参列表)
* 构造方法调用的技巧:
* - new 构造方法名(实参列表)
*
* 8、构造方法调用执行之后,有返回值吗?
* 每一个构造方法实际上执行结束之后都有返回值,但是这个“return 值”这样的语句不需要写,
* 并且返回值类型是构造方法所在类的类型。
*
* 9、当一个类中没有定义任何构造方法时,系统默认给该类提供一个无参数的构造方法,这个方法被称为缺省构造器。
*
* 10、当一个显示的将构造方法定义出来了,那么系统将不再为这个类提供默认的缺省构造器。
* 建议开发中手动的为当前类提供无参数的构造方法,因为无参数的构造方法太常用
*
* 11、构造方法支持重载机制。在一个类中编写多个构造方法,这多个构造方法显然已经构成方法重载机制
*
* */
public class ConstructorTest01 {
public static void main(String[] args) {
// 以下程序创建了2个对象,只要构造函数调用就会创建对象,并且一定会在堆内存中开辟空间
User u1=new User();
User u2=new User(3);
//调用带有static关键字的方法:类名.方法名
ConstructorTest01.doSome();
//调用不带有static关键字的方法:引用.方法名
ConstructorTest01 t1=new ConstructorTest01();
t1.doOther();
}
public static void doSome(){
System.out.println("do some!");
}
public void doOther(){
System.out.println("do other!");
}
}
下面的代码演示了构造方法的第二个作用:
package pack01;
/*
* 构造方法的两个作用:
* 1、创建对象
* 2、创建对象的同时,初始化实例变量的内存空间,给实例变量赋值。
*
* 成员变量之实例变量,属于对象级别的变量,这种变量必须先有对象才能有实例变量。
* 实例变量没有手动赋值的时候,系统默认赋值,那么这个系统默认赋值是在什么时候完成的?
* 是在类加载的时候吗?
* 不是,因为类加载的时候只加载了代码片段,还没有来的及创建对象,所以此时实例变量并没有初始化。
* 实际上,实例变量的内存空间是在构造方法执行的过程中完成开辟的,此时完成了初始化。
* 系统在默认赋值的时候,也就是在构造方法执行的过程中完成的赋值。
*
* */
public class ConstructorTest02 {
// 在IDEA中如何查看访问的是哪个元素,查看访问的是哪个方法?
// 按住ctrl键,鼠标移动到查看的元素上,出现下划线的时候开始单击。
public static void main(String[] args) {
Account act1=new Account();
System.out.println("账号:"+act1.getActno());
System.out.println("余额:"+act1.getBalance());
Account act2=new Account("小明");
System.out.println("账户:"+act2.getActno());
System.out.println("余额:"+act2.getBalance());
Account act3=new Account(33333333);
System.out.println("账户:"+act3.getActno());
System.out.println("余额:"+act3.getBalance());
}
}
package pack01;
//账户类
public class Account {
// 账号
private String actno; //实例变量/对象变量,也就是说,必须先有对象才能有对应的实例变量。即类在加载时并未对其赋值
// 余额
private double balance;
//无参数构造器
public Account(){
//初始化实例变量的空间,系统会默认赋值
//actno=null;
//balance=0.0;
}
//只有一个参数的构造器
public Account(String s){
actno=s;
//balance=0.0;
}
//只有一个参数的构造器
public Account(double d){
this.balance=d;
//actno=null;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
4、参数传递
普通数值变量在方法中传递时,传递的是值。
当一些类在传递时,传递的是地址,比如下面的这个代码示例:
public class Test01 {
public static void main(String[] args) {
Users u=new Users(20);
add(u);
System.out.println("main-->"+u.age);
}
private static void add(Users u) {
u.age++;
System.out.println("add-->"+u.age);
}
}
class Users{
int age;
public Users(int i){
age=i;
}
}
// 返回值
// add-->21
// main-->21
// Process finished with exit code 0
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d8b7gYD4-1649233821674)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220330162715992.png)]
5、this关键字
this关键字的示意图,在JVM中的抽象表示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KLiQYbGi-1649233821675)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220330204406474.png)]
使用this关键字的一个案例代码,可理解的去记忆this的使用方法:
package com.powernode.javase.test001;
/*
* 关于java语言中的this关键字:
* 1、this是一个关键字,翻译为:这个
* 2、this是一个引用,this是一个变量,this变量中保存的内存地址指向自身,this存储在JVM堆内存java对象内部。
* 3、创建100个java对象,每一个对象都有this,也就是说有100个不同的this
* 4、this可以出现在“实例方法”当中,this指向当前正在执行这个动作的对象。
* 5、this在多数情况下是可以省略不写的
* 6、this不能使用在带有static关键字的方法或者静态变量中
*
* */
public class Customer {
// 姓名
String name;
static int a=10;
// 构造方法
public Customer(){
}
/*
不带有static关键字的一个方法
顾客购物的行为
每一个顾客购物最终的结果是不一样的
所以这个购物属于对象级别的行为
由于每一个对象在执行购物这个动作的时候最终结果不同,所以购物这个动作必须有"对象"的参与
重点:没有static关键字的方法称为"实例方法",实例方法怎么访问? “引用.”
重点:没有static关键字的变量称为"实例变量"
注意:当一个行为/动作执行的过程中是需要对象参与的,那么这个方法一定要定义为"实例方法",不要带有static关键字
*/
public void shopping(){
System.out.println(this.name+"在购物!");
}
public static void doSome(){
// 这个执行过程中没有“当前对象” ,因为带有static关键字的方法是通过类名的方式访问的
// 或者说这个“上下文”当中没有“当前对象”,自然也不存在this(this代表的正是当前正在执行这个动作的对象)
// 以下程序为什么编译出错?
// doSome方法不是对象去调用,是一个类名去调用,执行过程中没有对象
// name是一个实例变量,以下代码的含义是访问当前对象的name,没有当前对象,自然也就不能访问当前对象的name
// System.out.println(this.name);
// 要想访问name这个实例变量的话应该怎么去做?
// System.out.println(name)报错
// 可以采用以下方案,但是以下方案,绝对不是访问的当前对象的name
// 创建对象
Customer c=new Customer();
System.out.println(c.name);
}
}
public class ThisTest{
// 本案例展示了一个错误的实例引用方法
// 实例变量(引用.的方式访问)
int num=10;
// 带有static关键字的方法
// JVM负责调用main方法
public static void main(String[] args) {
System.out.println(num);
}
}
package com.powernode.javase.test001;
public class CustomerTest {
public static void main(String[] args) {
// 创建对象
Customer c1=new Customer();
c1.name="zhangsan";
c1.shopping();
Customer c2=new Customer();
c2.name="lisi";
c2.shopping();
// 调用带有static关键字的方法 doSome
// 采用“类名.”的方式访问,显然这个方法在执行的时候不需要对象的参与
Customer.doSome();
}
}
this的最终解释
package com.powernode.javase.test003;
/*
* 最终结论:
* 在带有static的方法当中不能“直接”访问实例变量和实例方法
* 因为实例变量和实例方法的使用都需要对象的存在,
* 而static的方法中是没有this的,也就是说当前对象是不存在的,
* 自然也就无法访问当前对象的实例变量和实例方法
* */
public class ThisTest {
public static void main(String[] args) {
// 调用doSome方法
ThisTest.doSome();
// static方法中没有this,所以不能直接使用this.doOther
// 调用doOther方法
ThisTest tt=new ThisTest();
tt.doOther();
}
public static void doSome(){
System.out.println("do Some!");
}
public void doOther(){
System.out.println("do Other!");
}
// 以下代码的含义是调用当前对象的doOther方法
public void run(){
System.out.println("run execute!");
this.doOther();
}
}
this关键字什么时候不能省略?
package com.powernode.javase.test003;
/*
* this什么时候不能省略?
* this用来区分实例变量和局部变量的时候不能省略!
* */
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id; // 这里的this就不能省略!
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name; // 这里的this就不能省略!
}
}
上述关于 this关键字 的代码讲述了this在实例方法或实例变量当中的使用技巧,下述的代码演示了 this关键字 在构造方法中的使用技巧:
package com.powernode.javase.test005;
/*
* 自定义的日期类型
* this可以在哪里使用?
* 1、可以使用在实例方法当中,代表当前对象【语法格式:this.】
* 2、可以使用在构造方法中,通过当前的构造方法来调用其他的构造方法【语法格式:this(实参);】
*
* 重点记忆:this()这种语法只能出现在构造函数的第1行。
*
* */
public class Date {
private int year;
private int month;
private int day;
/*
* 需求:当程序员调用无参数的构造方法时,默认创建的日期是“1970-1-1”
* */
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public Date() {
// this.year=1970;
// this.month=1;
// this.day=1;
//以上代码可以通过调用另外一个构造方法来完成
//但前提是不能创建新的对象,以下代码创建了一个新的对象
// new Date(1970,1,1)
//需要采用以下的语法来完成构造方法的调用
//这种方法不会创建新的对象,但同时又可以达到调用其他的构造方法
this(1970,1,1);
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
// 对外提供一个方法,将日期打印输出至前台
public void print(){
System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
}
}
this关键字 不严谨的地方,是否存在static时出现的情况如下述代码所示,这里需要注意,可能以后会因为这样肤浅而又不会引人注意的问题而引发严重的错误,尤其需要注意,所以以后写代码就要规规矩矩的去做。
package com.powernode.javase.test005;
/**
* 什么时候程序运行的时候出现空指针异常?
* 空引用访问实例相关的数据,因为实例相关的数据就是对象相关的数据。
* 这些数据在访问的时候,必须有对象的参与,当空引用的时候,对象不存在,
* 访问这些实例数据一定会出现空指针异常。
*
* 实例相关的数据包括:
* 实例变量【对象需要存在】
* 实例方法【对象需要存在】
*
*
* */
public class Test {
public static void main(String[] args) {
Test.doSome();
doSome();
Test t=new Test();
t.doSome();
//引用为空
//下述代码实际未用到对象,实际为Test.doSome()
//带有static关键字的方法,即可以采用类名的方法访问,也可以采用引用的方法访问,
//但采用引用.的方式访问的时候,实际为采用类名的方式访问的,个人可以认为这是一个不严谨的地方
t=null;
t.doSome();
}
public static void doSome(){
System.out.println("do Some!");
}
}
6、static关键字
带有static关键字的成员变量之静态变量在代码中的实际使用技巧:
package test008;
public class Chinese {
// 身份证号码
String id;
// 姓名
String name;
// 国籍 【每一个对象都是由“Chinese类”实例化的,所以每一个中国人的国籍都是“中国”】
// 无论通过Chinese类实例化多少个java对象,这些java对象的国籍都是“中国”
// 可以在变量前添加static关键字
// 静态变量,静态变量在类加载的时候初始化,不需要创建对象,内存就开辟了。
// 静态变量存储在方法区内存中
static String country="中国";
public Chinese(){
// this.id=null;
// this.name=null;
// this.country=null;
}
public Chinese(String id, String name){
this.id=id;
this.name=name;
}
}
package test008;
public class ChineseTest {
public static void main(String[] args) {
Chinese zhangsan=new Chinese("1","张三");
System.out.println(zhangsan.id+","+zhangsan.name+","+Chinese.country );
Chinese lisi=new Chinese("2","李四");
System.out.println(lisi.id+","+lisi.name);
}
}
带有static关键字的成员变量之静态变量在JVM中的存储示意图:实际上存储在方法区内存中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M20Q022S-1649233821675)(C:\Users\ls\AppData\Roaming\Typora\typora-user-images\image-20220331101413576.png)]
static关键字定义“静态代码块”时候的使用方法:
package com.powernode.javase.test010;
/**
* 可以使用static关键字来定义“静态代码块”:
* 1、语法格式:
* static{
* java语句;
* }
*
* 2、静态代码在类加载的时候执行,并且只执行一次
*
* 3、静态代码块可以在一个类中编写多个,并且遵循自上而下的顺序执行
*
* 4、静态代码块的作用是什么?怎么使用?用在哪里?什么时候使用?
* - 和具体的需求有关,例如项目中要求在类加载的时刻/时机执行代码完成日志的记录,
* 那么这段记录日志的代码可以编写到静态代码块中,完成日志记录
* - 静态代码块是java为程序员准备的一个特殊时刻,这个特殊的时刻被称为类加载时刻。
* 若希望在此处执行一段特殊的程序,就可以放到代码块中你
*
* 5、通常在静态代码块中完成预备工作,并完成数据的准备工作,例如:初始化连接池,解析XML配置文件......
*/
public class StaticTest01 {
static{
System.out.println("类加载!1");
}
static{
System.out.println("类加载!2");
}
static{
System.out.println("类加载!3");
}
static{
System.out.println("类加载!4");
}
public static void main(String[] args){
System.out.println("main begin!");
}
}
实例代码块的使用技巧,该部分实际应用情况较少,了解一下。知道有这个东西即可,
package com.powernode.javase.test010;
/**
* 实例语句块/代码块【了解内容,使用的非常少】
* 1、实例代码块可以编写多个,也是遵循自上而下的顺序依次执行
* 2、实例代码块在构造方法执行之前执行,构造方法依次执行,实例代码块赌赢执行一次
* 3、实例代码块也是java语言为程序员准备的一个特殊时机,这个特殊时机被称为:对象初始化时机
*/
/
public class Tests {
// 构造函数
public Tests(){
System.out.println("Test类的缺省构造器执行");
}
// 实例代码块
{
System.out.println(1);
}
// 实例代码块
{
System.out.println(2);
}
// 实例代码块
{
System.out.println(3);
}
public static void main(){
System.out.println("main begin!");
new Tests();
}
}
static关键字在main方法中的玩法
package com.powernode.javase.test010;
// 静态方法中无法直接访问实例变量和实例方法
public class MainTest {
// public表示公开的,在任何位置都是可以访问的
// static表示静态的,使用“类名.”的方式访问即可,不需要创建对象,就可以调用main方法
// void 表示main方法结束之后不需要返回任何值
// main是main方法的方法名
// (String[] args)是main方法的形式参数列表
public static void main(String[] args){
main(10);
main("hello, world!");
}
public static void main(int i){
System.out.println(i);
}
public static void main(String args){
System.out.println(args);
}
}
/**
* class 类{
* 静态代码块;
* 实例代码块;
*
* 静态变量;
* 实例变量;
*
* 构造方法;
*
* 静态方法;
* 实例方法;
* }
*/
/
7、继承
以下三个代码演示了一个继承的案例
package com.powernode.javase.test012;
public class Count {
private String actno;
private double price;
public Count(){
}
public Count(String actno, double price) {
this.actno = actno;
this.price = price;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
package com.powernode.javase.test012;
public class CreditAccount extends Count{
private double credit;
public CreditAccount() {
}
public CreditAccount(double credit) {
this.credit = credit;
}
public double getCredit() {
return credit;
}
public void setCredit(double credit) {
this.credit = credit;
}
}
package com.powernode.javase.test012;
/**
* 关于java语言中的继承
* 1、继承是面向对象三大特征之一,(封装、继承、多态)
*
* 2、继承的基本作用:代码复用。
* 最重要的作用:有了继承之后才会有以后的“方法覆盖”和“多态机制”
*
* 3、[修饰符列表] class 类名 extends 父类名{
* 类体=属性+方法;
* }
*
* 4、java语言中的继承只支持单继承,一个类不能同时继承多个类,只能支持继承一个类。在C++中支持多继承
*
* 5、关于继承中的一些术语:
* B类继承A类,其中:
* A类称为:父类、基类、超类、superclass
* B类称为:子类、派生类、subclass
*
* 6、在java语言中子类继承父类都继承哪些数据呢?
* - 私有的不支持继承
* - 构造方法不支持继承
* - 其他数据都可以支持继承
*
* 7、虽然java语言当中只支持单继承,但是一个类也可以间接继承其他类,例如:
* C extends B{
*
* }
* B extends A{
*
* }
* A extends T{
*
* }
* C直接继承B类,但是C类间接继承T、A类
*
* 8、java语言中假设一个类没有显示的继承任何类,但该类默认继承JavaSE库当中提供的java.lang.Object类
*
*/
public class ExtendsTest {
public static void main(String[] args) {
ExtendsTest et=new ExtendsTest();
String s=et.toString();
System.out.println(s);
CreditAccount act=new CreditAccount();
act.setActno("act-001");
act.setPrice(-1000);
System.out.println(act.getPrice());
}
}
遇到多重继承时,到底是继承的哪个类中的方法?以下的代码演示了继承的规则
package com.powernode.javase.test012;
public class ExtendsTest2 {
public static void main(String[] args) {
C c=new C();
c.doSome(); //这里调用的doSome方法是从B类中继承过来的doSome方法!
}
}
class A{
public void doSome(){
System.out.println("do Some!");
}
}
class B extends A{
}
class C extends B{
}
8、方法覆盖
方法覆盖和方法重载的区别:方法重载是在一个类中构造多个方法名相同、形参列表不同的方法;方法覆盖是在多个类中构造方法名相同、形参列表不同的方法,尤其在继承的类中用的比较多
下面的这个代码:Animal是super,Bird和Cat是子类,Yingwu是Bird的子类,一共五个代码块,演示了方法覆盖的使用技巧:
package com.powernode.javase.test012;
/**
* 回顾java语言中方法的重载:
* 1、方法的重载又称为Overload
*
* 2、方法重载什么时候使用?
* 当在同一个类当中,方法完成的功能是相似的,建议方法名相同,这样方便程序员编程,
* 就像在调用一个方法似的。代码美观。
*
* 3、什么条件满足之后构成方法重载?
* *在同一个类当中
* *方法名相同
* *参数列表不同:类型、顺序、个数
*
* 4、方法重载和什么无关?
* *和方法的返回值类型无关
* *和方法的修饰符列表无关
*
*
* 关于java语言中方法的覆盖:
* 1、方法覆盖又被称为方法重写,英语单词:override【官方的】/overwrite
*
* 2、什么时候使用方法重写?
* 当父类中的方法已经无法满足当前子类的业务需求,
* 子类有必要将父类中继承过来的方法进行重写,
* 这个重新编写的过程称为方法重写/方法覆盖
*
* 3、什么条件满足之后会发生重写呢?
* * 方法重写发生在具有继承关系的父子类之间
* * 返回值类型相同,方法名相同,形参列表相同
* * 访问权限不能更低,可以更高
* * 方法重写的时候:抛出异常不能更多,可以更少。【以后讲,讲完异常之后才能解释】
*
* 4、建议方法覆盖时,直接复制;不要编写,容易出错,导致没有发生覆盖!!!
*
* 5、注意:
* 私有方法不能继承,所以不能覆盖
* 构造方法不能继承,所以不能覆盖
* 静态方法不存在覆盖。【讲完多态之后讲】
* 覆盖只针对方法,不针对属性
*/
public class OverrideTest01 {
public static void main(String[] args) {
// 创建动物对象
Animal a=new Animal();
a.move();
// 创建猫科动物
Cat c=new Cat();
c.move();
// 创建鸟
Bird b=new Bird();
b.move();
Yingwu y=new Yingwu();
y.move();
}
}
package com.powernode.javase.test012;
// 动物类
public class Animal {
// 动物是可以移动的
public void move() {
System.out.println("动物在移动!");
}
}
package com.powernode.javase.test012;
//猫
public class Cat extends Animal {
public void move(){
System.out.println("猫在走猫步!");
}
}
package com.powernode.javase.test012;
// 飞禽类
public class Bird extends Animal{
public void move(){
System.out.println("鸟在水里游!");
}
}
package com.powernode.javase.test012;
public class Yingwu extends Bird {
// 这里的move相当于是覆盖的Bird的move方法,而不是Animal中的move方法
public void move(){
System.out.println("鹦鹉只会扑腾翅膀!");
}
}
9、多态
多态的语法机制:存在继承关系的不同类之间如何相互调用。下述代码讲解了向上继承和向下继承的语法规则和案例:
package test001;
/**
* 关于java语法当中的多态机制:
* 1、Animal、Cat、Bird之间的关系:
* Cat继承Animal
* Bird继承Animal
*
* 2、面向对象的三大特征:封装、继承、多态
*
* 3、关于多态当中涉及到的几个概念:
* * 向上转型(upcasting)
* 子类型--->父类型
* * 向下转型(downcasting)
* 父类型--->子类型。
* 又被称为:强制类型转换 【需要加强制类型转换符】
* * 需要记住的是:
* 无论是向上转型还是向下转型,两个类型之间必须有继承关系
* 没有继承关系,程序是无法编译通过的
*
*
*/
public class Test {
public static void main(String[] args) {
// 以前写的程序
Animal a1=new Animal();
a1.move();
Cat c1=new Cat();
c1.move();
c1.catchMouth();
Bird b1=new Bird();
b1.move();
// 使用多态语法机制
/*
* 1、Animal和Cat之间有继承关系,Animal是父类,Cat是子类
*
* 2、Cat is a Animal【合理的】
*
* 3、new Cat() 创建的对象的类型是Cat,a2这个引用的数据类型是Animal,可见它们之间进行了类型转换
* 子类型转换为了父类型,称为向上转型/upcasting,或者称为自动类型转换。
*
* 4、java中允许这种语法:父类型引用指向子类型对象
*
*
* */
Animal a2=new Cat();
/*
* 1、java程序永远都分为编译阶段和运行阶段
*
* 2、先分析编译阶段,再分析运行阶段,编译无法通过,根本是无法运行的
*
* 3、编译阶段检查a2这个引用的数据类型为Animal,由于Animal.class
* 字节码文件中有move()方法,所以编译通过。这个过程我们称之为静态绑定,编译阶段绑定
* 只有静态绑定成功之后才会有后续的运行
*
* 4、在程序运行阶段,JVM堆内存当中真实存在的对象是Cat对象,那么以下在程序运行阶段
* 一定会调用Cat对象的move()方法,此时发生了程序的动态绑定,运行阶段绑定
*
* 5、无论Cat类有没有move方法,运行阶段一定调用的是Cat的move()方法,
* 因为底层真实对象就是Cat对象
*
* 6、父类型引用指向子类型对象这种机制导致程序存在编译阶段绑定和运行阶段绑定两种不同的形态/状态
* 这种机制可以称为一种多态语法机制
*
* */
a2.move();
/*
* 分析以下程序为什么不能调用?
* 因为编译阶段 编译器检查到a2的类型是Animal类型,
* 从Animal.class字节码文件中查找catchMouth()
* 方法,最终没有找到该方法,导致静态绑定失败,没有绑定成功
* 也就是说编译失败了,更别谈运行阶段
*
* */
//a2.catchMouth();
/*
* 需求:假设想让以上的对象执行catchMouth()方法,怎么办?
* a2是无法直接调用的,因为a2的类型Animal,Animal中没有catchMouth()方法
* 我们可以将a2强制类型转换为Cat类型
* a2的类型是Animal(父类),转换成Cat类型(子类),被称为向下转型/downcasting/强制类型转换
*
* 注:向下转换也需要两种类型之间存在继承关系。不然编译报错,强制类型转换需要添加强制类型转换符号
*
* 什么时候需要向下转型呢?
* 当调用的方法是子类型中特有的,在父类型中不存在,就必须向下转型
*
* */
Cat c2=(Cat) a2;
c2.catchMouth();
// 父类型引用指向子类型对象【多态】
Animal a3=new Bird();
/*
* 1、以下程序编译阶段没有问题,因为编译器检查到a3的数据类型是Animal
* Animal和Cat之间存在继承关系,并且Animal是父类型,Cat是子类型
* 父类型转换为子类型叫做向下转型,语法合格
*
* 2、程序虽然编译通过,但程序在运行阶段会出现异常,因为JVM堆内存当中真实存在的对象是Bird类型
* Bird对象无法转换成Cat对象,因为两者之间不存在任何继承关系,此时出现了著名的异常:
* java.lang.ClassCastException
* 类型转换异常,这种异常总是在向下类型转换的时候发生
* */
// Cat c3=(Cat)a3;
/*
* 1、以上异常只有在强制类型转换的时候会发生,也就是说“向下转型”存在隐患(编译通过,但是运行阶段出错)
* 2、向上类型转换只要编译通过,运行就不会出错
* 3、向下转换编译通过,运行可能错误:Animal a3=new Bird(); Cat c3=(Cat)a3;
* 4、怎么避免出现向下转型出错呢? ClassCastException
* 使用instanceof运算符可以避免出现以上的异常。
*
* 5、instanceof运算符怎么调用?
* 5.1 语法格式:
* (引用 instanceof 数据类型名)
* 5.2 以上运算符的执行结果是布尔类型,结果可能是true/false
* 5.3 关于运算结果 true/false
* 假设:(a instanceof Animal)
* true表示: a这个引用指向的对象是一个Animal类型
* false表示:a这个引用指向的对象不是一个Animal类型
*
* 6、Java规范中要求:在强制类型转换之前,建议采用instanceof运算符进行判断,避免ClassCastException异常的发生
* */
if (a3 instanceof Cat){
Cat c3=(Cat)a3;
c3.catchMouth();
}else if(a3 instanceof Bird){
Bird b2=(Bird)a3;
b2.fly();
}
}
}
package test001;
public class Animal {
public void move(){
System.out.println("动物在悄悄的搞事情!");
}
}
package test001;
public class Cat extends Animal{
// 重写父类继承过来的方法
public void move(){
System.out.println("猫在走鸟步!");
}
// 不是从父类中继承过来的方法
// 这个方法是子类对象特有的方法
public void catchMouth(){
System.out.println("猫在抓杰克!");
}
}
package test001;
public class Bird extends Animal{
// 重写父类继承过来的方法
public void move(){
System.out.println("鸟儿在水里游!");
}
public void fly(){
System.out.println("Bird fly!");
}
}
多态的主要作用:降低程序的耦合度,提高程序的扩展力! 下述的5个代码块展示了如何实现低耦合:
package test002;
/**
* 多态在实际开发中的作用,以下以主人喂养宠物为例说明多态的作用:
* 1、分析:主人喂养宠物这个场景要实现需要进行类型的抽象:
* - 主人【类】
* - 主人可以喂养宠物,所以主人有喂养的这个动作
* - 宠物【类】
* - 宠物可以吃东西,所以宠物有吃东西的这个动作
*
* 2、面向对象编程的核心:定义好类,然后将类实例化为对象,给一个环境驱使一下,
* 让各个对象之间协作起来形成一个系统
*
* 3、多态的作用是什么?
* 降低程序的耦合度,提高程序的扩展力
* 能使用多台尽量使用多台
* 父类型引用指向子类型对象
*
* 核心:面向抽象编程,尽量不要面向具体编程。
*/
public class Test {
public static void main(String[] args) {
Master zhangsan=new Master();
Cat tom=new Cat();
zhangsan.feed(tom);
Dog erha=new Dog();
zhangsan.feed(erha);
}
}
package test002;
/**
* 降低程序之间的耦合度【解耦合】,
* 提高程序的扩展力【软件开发的一个很重要的目标】
*
*
*/
public class Master {
// 下述代码的耦合度很高
/* public void feed(Cat c){
c.eat();
}
public void feed(Dog d){
d.eat();
}*/
public void feed(Pet pet){
pet.eat();
}
}
package test002;
public class Pet {
public void eat(){
System.out.println("宠物正在吃东西!");
}
}
package test002;
public class Dog extends Pet{
public void eat(){
System.out.println("小狗想啃骨头!");
}
}
package test002;
public class Cat extends Pet{
public void eat(){
System.out.println("TOM在吃杰克!");
}
}
10、final关键字
final修饰的类、方法、变量都添加了限制。具体限制情况可以根据下述代码进行理解。
package test003;
/**
* 关于java语言中final关键字:
* 1、final是一个关键字,表示最终的,不可变的
* 2、final修饰的类无法被继承
* 3、final修饰的方法无法被覆盖
* 4、final修饰的变量一旦被赋值后,不可被重新赋值
* 5、final修饰的变量??? 变量的解释如下述代码所示
* 6、final修饰的引用??? 一旦引用后,无法修改,且无法被垃圾回收器回收
* 7、final修饰的实例变量,一般和static联合使用,被称为常量
* 关于IDE如何连接源码????
*
* 对于以后大家所学习的类库,一般都包括三个部分:
* 1、源码 【可以看源码来理解程序】
* 2、字节码 【程序开发过程中使用的就是这部分】
* 3、帮助文档 【java的DOC文档,对源码的解释说明被提取出来,更方便程序的开发】
*
*/
public class FinalTest01 {
/*
* 成员变量之实例变量
* 实例变量有默认值+final修饰的变量,一旦被赋值则不能被重新赋值
* 综合考虑,java语言最终规定实例变量使用final修饰之后,必须手动赋值,不能采用系统默认值
* */
// 第一种解决办法
final int ages=10;
// 第二种解决办法
final int num;
public FinalTest01(int aaa){
this.num=aaa;
}
public static void main(String[] args) {
int k=10;
k=200;
final int i=2;
// 不可二次赋值
final int age;
age=20;
}
}
package test003;
public class FinalTest03 {
public static void main(String[] args) {
// 创建用户对象
User u=new User(100); // User u=0x1234
// 又创建了一个对象
// 程序执行到此处表示以上对象已经变成了垃圾数据,等待垃圾回收
u=new User(200); // u=0x3242
// 创建用户对象
final User us=new User(100); // 一旦引用后,无法修改,且无法被垃圾回收器回收
us.age=40;
us.age=33; // final修饰的引用虽然指向某个对象之后不能再指向其他对象,但是所指向对象内部的内存是可以被修改的
}
}
final如何修饰常量???
final修饰的实例变量,一般和static联合使用,被称为常量
package test003;
public class FinalTest04 {
public static void main(String[] args) {
System.out.println("圆周率:"+Math.PI);
}
}
class Chinese{
/*
* 国籍
* 需求:每一个中国人的国籍都是中国,且无法被修改,为了防止国籍被修改,建议添加final修饰
* final修饰的变量是不可被修改的,这种变量一般和static联合使用,被称为“变量”
* 变量的定义语法格式:
* public static final 类型 常量名=值;
*
* java规范中要求所有变量的名字全部大写,每个单词之间使用下划线连接
* */
// static final String country="中国";
public static final String COUNTRY="中国";
}
class Math{
public static final double PI=3.14;
}
总之,final修饰的东西不能变
11、package/import
package和import一般都会同时出现,使用技巧如下:
package packages;
/**
* 关于java语言当中的包机制:
* 1、包也被称为package,java中引入package这种语法机制主要是为了方便程序的管理
* 不同功能的类分门别类放到不同的软件包当中,查找比较方便,管理比较方便,容易维护。
*
* 2、怎么定义package呢?
* 在java源程序的第一行上编写package
* package只能编写一个语句
* -语法结构
* package 包名;
*
* 3、包名的命名规范:
* 公司域名倒序+项目名+模块名+功能名
* 采用这种方式命名时重复的概率低,因为公司域名具有全球唯一性
*
* 例如:
* cn.edu.bjut.info.compute.ls
*
* 4、包名要求全部小写,包名也是标识符,必须遵守标识符的命名规则
*
* 5、一个包将来对应的是一个目录
*
* 6、使用了package机制之后,应该怎么编译?怎么运行呢?
* - 使用了package机制之后,类名不再是Test01了, 类名是cn.edu.bjut.info.compute.ls.Test01
* - 编译:javac java源文件路径(在硬盘上生成一个class文件:Test01.class)
* - 手动方式创建目录,将Test01.class字节码文件放到指定的目录下
* - 运行: java cn.edu.bjut.info.compute.ls.Test01
*
* 还有一种方式:编译+运行 (javac -d . *.class)
* 编译:
* javac -d 编译之后存放路径 java源文件的路径
* 运行:
* 切换到包的目录下
*/
// import test002.Cat;
import test002.*;
/**
* import语句用来完成导入其他类,同一个包下的类不需要导入,
* 不在同一个包下需要手动导入。
*
* import语法格式:
* import 类名
* import 包名.*
*
* import语句需要放置在package语句之下,class语句之上
*
*/
public class Test01 {
public static void main(String[] args) {
// 调用别的包下面的文件,只是这种方法比较麻烦
test002.Cat c=new test002.Cat();
//也可以import包后再使用
Cat c2=new Cat();
// java.lang.* :不需要手动引入,系统自动引入
// lang: language语言包,是java语言的核心类,不需要手动引入。
String s="abc";
System.out.println(s);
// 直接编写以下代码编译错误,因为Date类没有找到
// Date d=new Date();
java.util.Date d=new java.util.Date();//也可以import这个类
}
}
/**
* 最终结论:
* 什么时候需要import?
* 不是java.lang包下,并且不在同一个包下的时候,需要使用import进行引入
*/
12、访问控制权限
package test005;
/**
* 访问控制权限修饰符:
* 1、访问控制权限修饰符用来控制元素的访问范围
* 2、访问控制权限修饰符包括:
* public 表示公开的,在任何位置都可以访问
* protected 同包下可以访问,子类下可以访问
* 缺省 同包下可以访问,子类不可以访问
* private 表示私有的,只能在本类中访问
* 3、访问控制权限修饰符可以修饰:类、变量、方法...
* 4、当某个数据只希望在子类使用,使用protected修饰
*
* 5、修饰符的范围:
* private<缺省<protected<public
*/
public class Test01 {
/**
* 类只能采用public或缺省的修饰符进行修饰。【内部类除外】
*/
/
public static void main(String[] args) {
User u=new User();
System.out.println(u.i);
System.out.println(u.num);
}
}
前三章总结
第一章:java的环境搭建
编写helloworld
配置环境变量
classpath/path
注释
public class和class的区别
第二章:java语言基础
标识符
关键字
字面值
变量
数据类型
运算符
控制语句
方法
递归
第三章:java的核心
面向对象和面向过程的区别
面向对象的三大特征
OOA、OOD、OOP
类和对象的概念
类的定义
对象的创建和使用
JVM内存管理
参数传递
面向对象的封装性
面向对象的继承
面向对象的多态
this关键字
static关键字
final关键字
访问控制权限修饰符
构造函数
方法的覆盖/重写
package/import