第1章Java与面向对象程序设计
1.1Java语言特点
Java语言是一门简单的、面向对象的优秀编程语言,它具有跨平台性、可移植性、安全性、健壮性、编译和解释性、高性能和动态性等特点,支持多线程、分布式计算与网络编程等高级特性。
1.2代码的注释
(1)单行注释用“//”
(2)多行注释用“/*”开头,以“*/”结尾。
(3)文档注释用“/* *”开头,以“*/”结尾。
1.3Java开发环境搭建
(1)JRE是Java程序的运行环境,包含了Java虚拟机、Java基础类库,当一台计算机想运行Java编写的程序时,至少需要安装JRE.
(2)JDK是Java开发工具包,它包含了JRE,同时还包含了编译器以及很多Java程序调试和分析的工具。
第2章Java编程基础
2.1变量与常量
2.1.1 关键字和保留字
while | catch | double | break | try | switch |
void | assert | boolean | transient | super | package |
this | throw | throws | static | new | import |
return | strictfp | short | native | abstract | final |
public | volatile | long | if | extends | continue |
private | protected | goto | enum | const | |
instanceof | int | else | class | synchronized | |
finally | float | char | interface | case | |
default | do | for | byte | implements |
2.1.2数据类型
Java数据类型分为基本数据类型和引用数据类型。
byte(1B) | ||||
整型 | short(2B) | |||
int(4B) | ||||
数值型 | long(8B) | |||
基本数据类型 | ||||
浮点型 | float(4B) | |||
double(8B) | ||||
数据类型 | 字符型 | char(2B) | ||
布尔型 | boolean(没有明确) | |||
引用数据类型 | 类 | |||
接口 | ||||
数组 |
2.1.3变量的定义与赋值
变量必须先声明再使用。变量的赋值使用“=”,赋值的数据类型必须与声明的数据类型一致。变量赋值语法如下:
变量是可以改变值的量,在声明一个变量之后,它的值就可以被改变任意次。变量名的命名需要遵守小写字母开头的驼峰规则。
2.1.4常量
在变量声明语法前加上final关键字。常量一旦被赋值后,就不可以改变了。命名要求所有字母大写,单词用“-”隔开。
2.1.5变量的类型转换
自动类型转换
int num1 = 10;
double num2 = num1;
强制类型转换
float num3 = (float) num2;
2.2运算符与表达式
2.2.1算术运算符
二元运算符 | + | |
- | ||
* | ||
/ | ||
% | 取模运算,即求余数 | |
一元运算符 | num++ | 自增运算符,先返回num的值,再将num加1 |
++num | 自增运算符,先将num加1,再返回num的值 | |
num-- | 自增运算符,先返回num的值,再将num减1 | |
--num | 自增运算符,先将num减1,再返回num的值 |
2.2.2赋值运算符
赋值与扩展运算符
运算符 | 描述 | 运算符 | 描述 |
= | 将右边的值赋值给左边的变量,如num=5 | *= | 如num*=5,相当于num=num*5 |
+= | 如num+=5,相当于num=num+5 | /= | 如num/=5,相当于num=num/5 |
-= | 如num-=5,相当于num=num-5 | %= | 如num%=5,相当于num=num%5 |
2.3选择结构
2.3.1 if语句
Java有三种结构:顺序结构、选择结构、循环结构
一个if语句之后可以有0至多个else if语句,可以有0或1个else语句。
如果if选择结构只需执行一条语句,可以省略{ },{ }中的代码语句成为代码块。
语法格式如下:
if(条件表达式1){ //代码块1
}else if(条件表达式2){ //代码块2
}else if(条件表达式3){ //代码块3
}else{ //代码块n
}
2.3.2 switch语句
switch语句一般用于做一些精确值的判断。
语法格式如下:
switch(变量){
case 值1:
代码块1;
break;
case 值2:
代码块2;
break;
...
default:
代码块n;
break;
}
2.3.3 选择结构的嵌套
编写程序,判断一个年份是否为闰年。闰年的判断方法为:如果一个年份能被400除,那么该年是闰年。否则,如果这个年份不能被100整除,但可以被4整除,也是闰年。
if语句一般用于区间值的判断,switch语句只能用于确定值的判断。switch语句能够实现的if语句都可以实现,反之不行。
2.4循环结构
2.4.1 for语句
for循环是最常见的循环结构,语法格式如下:
for(循环初始化表达式;循环条件表达式;循环后的操作表达式) {
//循环体
}
2.4.2while语句
while语句,只要条件表达式的值为true,就会执行循环体,直到条件表达式的值为false才退出。
while循环一般用于不确定循环次数的场景。
语法格式如下:
while(条件表达式){
//循环体
}
2.4.3 do...while 语句
可能存在需要循环体至少执行一次的场景,可以使用。
do{
//循环体
}while(条件表达式);
2.4.4 break和continue语句
在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。continue只能终止某次循环,继续下一次循环。
确定循环次数使用for
不确定次数或想让循环永远循环 用while
想让循环体至少执行一次,用do...while
2.5方法
2.5.1 方法声明与调用
方法声明语法格式如下
修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2,...) {
//方法体;
return 返回值;
}
当声明了一个方法后,就可以使用代码在其他方法中调用它。调用方法语法格式
自定义方法名(实际参数1,实际参数2,...);
2.5.2方法重载
重载:只在小括号,即入参,折腾。
入参的类型不一样、入参的数量不一样
public void fun(int a,float b,char c){ }
2.6数组
2.6.1 数组概述
三种数组创建方式
(1)创建出制定长度的数组,数组有多长,就能存储多少数据
数据类型[ ] 数组名 = new 数据类型[数组长度];
(2)创建数组的同时向数组中存储数据,此时不需要指定数组长度,有多少元素则数组就多长
数据类型[ ] 数组名 = new 数据类型[ ]{元素1,元素2,元素3,...};
(3)简写方式
数据类型[ ] 数组名 = {元素1,元素2,元素3,...};
数据类型可以2是任意的基本数据类型和引用类型。
2.6.2 数组的常见操作
1、通过索引操作元素
数组元素的操作通过索引(下标)进行的,当创建了一个长度为n的数组后,索引范围是【0,n-1】
2、数组的遍历
数组的遍历一般使用for循环遍历,从0遍历到数组长度-1即可。
//从0~length-1,每次遍历时i都是当前索引
2.6.3数组排序算法
1、冒泡排序
冒泡排序:从序列的一端开始往另一端冒泡,依次比较相邻的两个数的大小。
设数组长度为N。
1.每轮比较相邻的前后两个数据,如果前面数据大于或者小于后面的数据,就将二个数据交换。
2.这样每轮对数组的第0个数据到N-1个数据进行一次遍历后,最大或者最小的一个数据就到数组第N-1个位置。
3. 第一轮比较到下标为N-1的数据(最后一个),以后每次比较都-1。
#include <stdio.h>
int main () {
int list[10] = {5,23,86,21,43,67,45,34,58,23};
int j, temp;
int i = 10;
int bool = 1;
while(bool)
{
bool = 0;
for (j = 1; j < i; j++)
if (list[j - 1] > list[j])
{
temp = list[j - 1];
list[j - 1] = list[j];
list[j] = temp;
bool = 1;
}
i--;
}
for (i = 0;i < 10; i++)
printf("%d\n",list[i]);
}
2、选择排序
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
- 1 :在长度为n的数组中,从第一个元素开始,假设第一个元素是最小的。
- 2 :遍历数组中剩下的n-1个元素,将每个元素与当前最小元素进行比较。如果找到一个更小的元素,则更新最小元素的索引。
- 3 :经过一次遍历后,将找到的最小元素与数组的第一个元素交换位置。这样,数组的第一个元素就是整个数组中的最小元素。
- 4 :对数组的剩余部分(从第二个元素到最后一个元素)重复上述步骤。每次迭代都会将剩余未排序部分中的最小元素移动到已排序部分的末尾。
2.6.4 二分查找法
它充分利用了数组元素有序的特点,每次查找都通过比较中间元素与目标元素的大小,将查找区间缩小一半,不断重复这个过程,直到找到目标元素或者确定目标元素不存在为止。
public class BinarySearch {
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 9};
int target = 5;
int result = binarySearch(arr, target);
System.out.println(result);
}
}
2.7JVM 中的堆内存与栈内存
2.7.1 堆和栈
虚拟机栈(保存正在运行的方法)
堆(保存引用类型的数据实体)
对于变量来说,在哪出生在哪里
对于数据来说,引用类型在堆里面,基本类型看变量。
第3章 面向对象程序设计(基础)
3.1 面向对象的概念
3.1.1 面向对象的特性
封装、继承、多态是面向对象的三大特性
3.2面向对象编程
3.2.1 类的定义
Java使用class关键字定义一个类。一个Java文件中可以有多个类,但最多只能有一个public修饰的类,并且这个类的类名必须与文件名完全一致。
类主要由变量(字段)和方法组成。
属性(变量、字段、域)定义格式如下:
修饰符 变量类型 变量名 = 【默认值】;
方法(函数、行为) 定义格式如下:
修饰符 返回值类型 方法名(形参列表) { }
在成员方法中,可以随意访问类中定义的成员变量。
3.2.2对象的创建与使用
要创建一个对象,必须先有一个类,然后通过new关键字创建一个对象。语法格式如下
类名称 对象名称 = new 类名称();
Student Stu2 = new Student();
成员变量和成员方法隶属于对象,不同对象之间的成员变量占用不同的地址空间,互不影响。
3.3构造方法
3.3.1什么是构造方法
构造方法的名称必须与类型相同,并且不能定义返回值,不能出现return关键字。构造方法的调用必须通过new关键字调用。语法格式如下:
修饰符 类名(形参列表){ }
3.3.2 构造方法的使用
Java中要求每一个类必须有构造方法,没有也会提供一个默认的无参数构造方法,称为“无参构造方法”。
//变量,成员变量。
String name;
int age;
//无参构造方法
public Student() {
System.out.println("无参构造执行了");
}
//有参构造方法
public Student(String stuName,int stuAge) {
name = StuName;
age = stuAge;
System.out.println("有参构造执行了");
}
//方法
void eat(String food){
System.out.println(name + "吃" + food);
}
3.4 this 关键字
3.4.1 this关键字介绍
this关键字解决重名问题
比如:创建两个Student对象,分别为stu1和stu2.当stu1调用eat()方法时,eat()方法中的this代表stu1这个对象;当stu2调用eat()方法时,eat()方法中的this代表stu2这个对象.
3.5 static关键字
3.5.1 静态变量
静态变量优于对象存在,随着类的加载就已经存在了,该类的所有实例共用这个静态变量,即共用同一份地址空间。建议使用类名.变量名进行调用。
在 Java 中,static
关键字用于修饰成员变量时,这个变量就成为类变量。
当static
用于修饰方法时,这个方法就是静态方法。
3.6包
3.6.1包的概念
- 在 Java 中,包(package)是一种组织类和接口的机制。它类似于文件夹,用于将相关的 Java 类型(类、接口、枚举、注释类型)组合在一起,方便管理和维护代码。
- 声明一个包的语法格式如下:
package com.yyds.unit3.demo;
3.6.2 类的访问与导包
使用import关键字导入Java中的包,语法格式如下:
import 包名.类名;
第4章 面向对象程序设计(进阶)
4.1封装
4.1.1 什么是封装
封装是指将数据(成员变量)和操作这些数据的方法(成员函数)包装在一起,形成一个独立的单元,也就是类(Class)。并且对外部隐藏类的内部实现细节,只提供一些公共的接口来访问和操作类中的数据。
4.1.2 访问修饰符
---给不给对象访问
访问修饰符可以修饰类、接口、变量、方法。
子类 | 只有private看不见 | private+default看不见 |
非子类 | 只有private看不见 | 只有public可以看见 |
4.1.3get()/set()方法
get()
和set()
方法是在面向对象编程中,用于访问(获取)和修改(设置)类的私有(private)成员变量的方法。它们是实现封装的重要工具。
假设我们有一个Person
类,其中包含姓名(name
)和年龄(age
)两个私有成员变量。
-
class Person { private String name; private int age; // get方法获取姓名 public String getName() { return name; } // set方法设置姓名 public void setName(String newName) { if (newName!= null &&!newName.isEmpty()) { name = newName; } } // get方法获取年龄 public int getAge() { return age; } // set方法设置年龄 public void setAge(int newAge) { if (newAge >= 0) { age = newAge; } } }
4.2继承
4.2.1 什么是继承
继承--大部分要复用,小部分要重构。
目的:为了重新实现父类的某些方法
4.2.2继承的使用
继承使用extends关键字
语法格式如下:
class 父类 {
}
class 子类 extends 父类{
}
子类加的属性全是新增
4.2.3 方法重写
重写:指的是重新实现父类的方法
重载:对一个类里面的方法重新加载
父类有这个方法是覆盖,没有是新增。
子类发扬光大 public void teach() 不能改
@Override 帮我们自动检查符不符合重写的语法规定
4.3super关键字
4.3.1 super关键字的使用
解决子类父类属性同名问题
可以通过super访问父类中被子类覆盖的方法或属性。---即调用同名父类
4.3.2 super与this对比
this----区分同名变量(就近原则)
4.4final关键字
被Java的final关键字修饰的东西不能改变
可以修饰:类、属性/变量、方法
final修饰的类不可以被继承,但是可以继承其他类。
final修饰的引用类型变量不能改变它的引用地址
类改变:被继承
方法改变:被重写
变量/属性改变:值的改变
4.5Object类
1、JDK希望所有类都有共同点
2、子类无法继承父类的私有成员。
3、toString()方法---用来把对象转成字符串
4、equals()方法---用来翻译什么叫做两个对象相等。
4.6多态
4.6.1 什么是多态
多种状态,同一个方法,不同的运行效果。
4.6.2 多态的实现
多态的范围仅限于成员方法。主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。
4.6.3 多态中变量与方法的调用
左----引用 右----对象实体
多态的,以父之名:编译看左,运行看右
和多态无关的,该干嘛就干嘛---编译、运行都看左
当父类引用指向了子类对象实体的时候,JDK把这个实体当成父类对象实体来使用。
4.7抽象类
4.7.1什么是抽象类
解决---父类的某些方法强制子类必须重写。
抽象类是结果,抽象方法是原因。
4.7.2 抽象类的定义与使用
Java的面向对象是单继承的,也就是说一个类只能继承一个类。
抽象类不能直接new 对象(可以new对象)
抽象类是有构造方法的
子类继承抽象类后,有两种选择。
1)子类继续抽象
2)子类把抽象方法全部实现
4.8接口
4.8.1什么是接口
接口的属性(常量),JDK不会帮我们赋初始值。
4.9内部类
4.9.1内部类
问题:一个类的内部,还可以细化进行分类,切这些局部只有当前类会用到
解决方案:内部类机制
三个关系:
1、Car和Main的关系:前面学过的关系
2、Car和AC的关系:外部类和内部类的关系
Car->AC:在普通访问的基础上,外部类还能访问内部类的private成员
AC->Car:内部类能直接随意访问外部类的成员(很特殊,依赖倒置了)
3、Main和AC的关系:没有直接的关系
Main->AC:通过外部类,只在创建对象有点特殊,当拿到某个类的内部类对象后,正常访问
AC->Main:和外部类一样
4.9.2成员内部类
4.9.3静态内部类
4.9.4局部内部类
类是解决什么问题:代码复用
类还有一个作用:用来表达复杂的数据
问题:如果我要临时性表达一个复杂数据
解决:局部内部类
4.9.5匿名内部类
匿名内部类----临时使用一个对象,该类又没有定义。
问题:临时使用一个对象,该类又没有定义
解决:匿名内部类
1)创建一个子类,实现了Teacher接口
2)重写了Teacher接口的teach方法
3)new了这个子类的对象
4)把这个子类对象作为fun方法的入参
成员内部类、静态内部类、局部内部类、匿名内部类(99%都是用这个)
第5章 异常
5.1异常概述
5.1.1什么异常
异常指的是程序运行过程中出现的不正常现象
问题:代码不一定100%能够执行
解决:Java语言对这种无法正常运行的代码有一种管理机制:异常处理机制
ArithmeticException 是类名
java.lang.ArithmeticException 全限定类名
原理:当某行代码无法正确执行的时候,会在该行产生一个对象用户保存错误信息
这种保存错误信息的对象称之为异常对象(不要理解成不正常的对象,而是保存异常信息的对象)
然后,这个对象就得有人处理:当前方法处理->调用这个方法的方法->交给JVM
JVM的处理:在控制台打印一堆红色字体(打印异常对象)
5.1.2Throwable与异常体系
public class Demo2 {
public static void main(String[] args) {
当某行代码不能正常运行的时候,抛出一个异常对象
抛出异常对象:说明这个对象是可以抛的
Java设计一种“可以抛的”对象:Throwable 对象
Throwable throwable = new Throwable();
先把光标放在类名上,然后按住键盘的 ctrl+H
Throwable 两个子类:Error、Exception
Error:从程序的角度解决不了的问题,让JVM去处理:爆红:在控制台把异常对象打印出来
Exception:可以从编码的角度处理
Exception 的子类分为两种:编译期异常、运行时异常(继承了RuntimeException)
背景:a.java -> a.class -> 运行结果
IDEA 工具会帮我们预编译,如果编译有问题,会在 IDEA 界面看到
int a = 1 / 0; // ArithmeticException 是运行时异常:编译期没有报红,在运行的时候才爆红
File file = new File("");
file.createNewFile(); // IOException 是编译期异常
}
}
5.2异常处理
// 方式一:通过 try...catch 发形式主动解决
try {
a = 2 / 0;
File tempFile = File.createTempFile("", "");
} catch (ArithmeticException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("sss");
}
System.out.println(a);
// 方式二:甩锅,在方法的小括号右边写: throws 异常类名
意思:当前方法不处理,交给调用这个方法的调用方去处理
fun();
}
public static void fun() throws IOException {
File tempFile = File.createTempFile("", "");
}
}
第6章Java常用类
6.1包装类
6.1.1 什么是包装类
--解决:基本数据类型无法表达“没有数据”这个概念
优点:1)可以表达“没有数据”
2)还赠送了两个字符串和数字互转的方法
缺点:1)占用的空间更大了
2)消耗的计算资源更大
比如: long L = 2415L; ----long类型 float f = 3.14f; -----float类型
6.1.2 自动拆箱与装箱
Integer a = 3;(装箱)
int b = a;(拆箱)
6.1.3 大数字运算
1、BigInteger (无限大整数)
2、BigDecimal (无限大小数)
6.2String类概述
6.2.1 String类
一旦String的值确定了,就不能再改变了。
字符串对象修改值的时候---字符串引用重新连接新的对象。
6.3StringBuilder类和StringBuffer类
6.3.1 StringBuffer类
6.3.2StringBuilder类
一次只能运行一个线程修改。
StringBuilder:速度快、线程不安全
StringBuffer:速度相对慢、线程安全
6.4时间和日期相关类
Date类:和SimpleDateFormat搭配使用,比较原始。
SimpleDateFormat类:是Java中的时间格式化类。
Calendar类:日历类,提供日期时间的计算方式。
获取当前时间的Calendar对象---static Calendar getInstance()
Random类:用于补充Math.random()的局限
UUID类:用于获取唯一的随机数
枚举类:(enum)允许用常量表示特定的数据片段,而且全部都以类型安全的形式表示。
定义如下:
修饰符 enum 枚举类名{
枚举值1,枚举值2,枚举值3,...
}