java基础编程(入门)
01基础知识
1.计算机基础
【1】进制
A.十进制转化二进制
除以2,求余数,商继续除以2,一直到0为止,从底下往上得到结果。
B.二进制转化十进制
1 | 1 | 0 | 0
2
3
∣
2
2
∣
2
1
∣
2
0
2^3 | 2^2 | 2^1 | 2^0
23∣22∣21∣20
8
+
4
+
0
+
0
=
12
8+4+0+0=12
8+4+0+0=12
【2】 计算机的储存方式
位(bit):0或1
字节(byte):8位1字节,数据储存的最小单位
1 KB=1024 Byte
1 MB=1024 KB
1 GB=1024 MB
1 TB= 1024 GB
1 PB= 1024 TB
1 EB= 1024 PB
1 ZB= 1024 EB
【3】命令提示符
进入文件夹:cd 文件夹1/文件夹2/文件夹3
返回上一级:cd …
回根目录: ls 查看当前目录下文件
清屏:command+k
退出:exit
2.JAVA语言开发环境搭建
【1】 Java虚拟机–JVM
Java跨平台(JVM翻译):可运行在各个平台中
【2】JRE & JDK
JRE:运行时环境,包含JVM和运行时需要的核心库类
JDK: JAVA程序开发工具包,包含JRE+开发工具
【3】程序开发步骤:
编写,编译,运行
javac HelloWorld.java
java HelloWorld
3.注释
【1】单行注释
// 这是单行注释
【2】多行注释
/*
这
是
多
行
注
释
*/
4.关键字:java本来就有的内容
【1】全是小写的纯英文字母
【2】有特殊颜色
5.标识符:我们自己定义的内容
规则:
【1】可以包含 英文字母26个(大小写), 0-9数字, $ 和 _
【2】不能数字开头
【3】不能是关键字
6.常量:固定不变的量
分类:
- 字符串常量(string):双引号之中一定是
- 整数常量(int):直接写的数字,没小数点
- 浮点数常量(float):直接写的数字,有小数点
- 字符常量(character):单引号之中的单个字符一定是
- 布尔常量(boolean):true / false
- 空常量(null):null 没有任何数据
TIPS:
- 两个单引号中间只能有一个字符
- 空常量不能直接用于输出
7.基本数据类型&内存占用(单位:字节)
- 整数型:byte(1) int(4)(默认) short(2) long(8)
- 浮点型:float(4) double(8)(默认)
- 字符型:char(2)
- 布尔型:boolean(1)
TIPS:
- 字符串不是基本类型
- 浮点类型可能是近似值
- 数据范围和字节数不相关 ex. float&long
- 浮点型中默认是double,若要是float,后缀要加上F
整数型中默认是int,若要是long,后缀要加上L
8.变量:可以改变的量
- 创建格式:数据类型 变量名; 数据类型 变量名 = 数据值;
- 基本使用:
【1】打印变量名称,显示内容
【2】long num = 30000000000L; float num = 2.5F;
【3】赋值1:变量名 = 数据值;
【4】赋值2:变量名 = 变量名;
TIPS:
【1】变量名直接不能重复
【2】定义变量后,一定要进行赋值
【3】变量使用不能超过作用域的范围
作用域:从定义变量开始到大括号为止
【4】同时创建相同数据类型变量:
- 数据类型 变量名1,变量名2,变量名3;
- 数据类型 变量名1 = 数据值1,变量名2 = 数据值2,变量名3 = 数据值3;
9.数据类型转换
【1】自动类型转换(隐式)
A.代码不需要特殊处理,自动完成
B. 数据范围从小到大
long num = 100;
double num = 2.5;
float num = 30; //30.0
【2】强制类型转换(显式)
A.代码需要进行特殊格式处理,不能自动完成
B.范围小的类型 范围小的变量名 = (范围小的类型)原本范围大的数据;
int num = int(100);
TIPS:
【1】谨慎使用强制转换
数据溢出:long强制转换为int
精度损失(小数位被舍弃):double强制转换为int
【2】byte/short/char 都可以发生数学运算
char:‘A’+1输出为66
【3】byte/short/char 在运算时,都会被提升为int类型,然后计算
【4】boolean类型不能发生数据类型转换
10.ASCII编码
02运算符:进行特定操作的符号
1. 算术运算符: 四则运算,取余数%,自增++,自减- -
TIPS:
如果运算中有不同数据类型,结果将会是范围大的那种
2. 加号的用法
【1】数字相加
【2】对于char类型,会通过ASCII转换为int再进行计算
【3】对于字符串String类型,加号起连接作用
任何数据和字符串连接都会变成字符串
3. 自增和自减
【1】++num或者num++
【2】单独使用时:前++和后++一样
【3】混合使用时:
A.前++:变量马上+1
B.后++:先用本来的,后+1
int num = 20;
System.out.println(++num); //21
System.out.println(num); //21
int num2 = 30;
System.out.println(num2++); //30
System.out.println(num2); //31
TIPS:
常量不能使用++或者- -
4.赋值运算符:
【1】基本赋值运算符:=
【2】符合赋值运算符:+=,-=,*=,/=,%=
a+=1 等于 a = a + 1
TIPS:
【1】常量不能使用赋值运算符
【2】复合赋值运算符其中包含一个强制类型转换
5. 比较运算符:==,<,>,<=,>=,!=
TIPS:
【1】返回结果一定是一个boolean值
【2】如果多次判断,不能连着写 不允许:1<x<2
6. 逻辑运算符:与(&&) 或(||) 非 (!)
与,或,具有短路效果:如果根据左边可以得到正确的结果,右边将不执行
TIPS:
【1】比较运算符只用于boolean
【2】与,或需要两个boolean,非只需要一个boolean
【3】与,或可以连接多个条件
7. 三元运算符:需要三个数据才能操作的运算符
【1】格式:数据类型 变量名称 = 条件判断 ? 表达式A:表达式B;
【2】流程:如果条件判断是true,将表达式A的值赋值给左边,否则将表达式B的值赋值给左边
TIPS:
【1】必须同时保证表达式A,B都符合左侧数据类型的要求
【2】三元运算符的结果必须被使用
//a > b ? a : b; 错误写法
03方法(基础)
1.概念
将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个功能。需要使用功能的时候可以调用。
2.定义
public static void 方法名称() {
方法体
}
TIPS:
【1】方法定义的先后无所谓
【2】方法定义不能产生嵌套包含关系
【3】想要执行方法,一定要调用方法
【4】方法在main之外
3.调用
【1】格式:方法名称();
04流程控制
1.顺序结构
2.选择结构(判断语句)
【1】if语句
//格式1
if (关系表达式) {
语句体;
}
//格式2
if (关系表达式) {
语句体1;
}else {
语句体2;
}
//格式3
if (判断条件1) {
语句体1;
}else if (判断条件2) {
语句体2;
}else if (...) {
...
}else {
语句体n;
}
【2】switch 语句
//格式
switch(表达式) {
case 常量值1:
语句体1;
break;
case 常量值2:
语句体2;
break;
...
default:
语句体n;
break; //可省略
}
TIPS:
【1】多个case后面的数值不能重复
【2】switch后的小括号中只能是以下数据类型:Byte/Short/Int/Char String/enum
【3】switch语句很灵活,前后可以颠倒,break语句可以省略
“匹配到哪个case就从哪个位置向下执行,直到遇到break或整体结束”
3.循环结构
【1】循环结构的基本组成部分
A.初始化语句:最开始时执行,只执行一次
B.条件判断:成立则继续,否则退出
C.循环体:重复要做的事
D.步进语句:每次循环最后都要进行
【2】for循环
for (初始化语句;布尔表达式;步进表达式) {
循环体;
}
【3】while循环
//标准格式
while (条件判断) {
循环体;
}
//拓展格式
初始化语句;
while (条件判断) {
循环体;
步进语句;
}
【4】do-while循环
//标准格式
do {
循环体;
} while (条件判断)
//拓展格式
初始化语句
do {
循环体;
步进表达式
} while (条件判断)
【5】三种循环的区别
A.如果判断条件从没满足过,for/while执行0次,do-while至少执行一次
B.for循环的变量在小括号中定义,只有循环内部可以使用
【6】循环控制:条件控制语句
A.break
可以在switch中使用,switch语句结束
可以在循环语句中使用,循环语句结束
B.continue
立刻跳过当前次循环剩余内容,马上开始下一次循环
【7】死循环
while(true){
循环体;
}
【8】循环嵌套
循环中放循环
05方法(拓展)
1. 方法完整定义格式
修饰符 返回值类型 方法名称(参数类型 参数名称,...) {
方法体;
return 返回值;
}
修饰符: public static 目前固定
参数:进入方法的数据
返回值:从方法中出来的数据
2. 方法的三种调用格式:
【1】单独调用:方法名称(参数);
【2】打印调用:System.out.println(方法名称(参数));
【3】复制调用:数据类型 变量名称 = 方法名称(参数);
TIPS:
返回值为void,只能进行单独调用
3. 有参数方法和无参数方法
小括号中有没有内容
4. 有返回值方法和无返回值方法
void为无返回值方法
TIPS:
【1】方法定义的先后无所谓
【2】方法定义不能产生嵌套包含关系
【3】想要执行方法,一定要调用方法
【4】如果方法有返回值,必须写 return 返回值;
【5】return后的返回值类型必须和方法的返回值类型一样
【6】对于一个没返回值的方法,return后不能有返回值,可以写return;且可以省略
【7】一个方法可以有多个return,但只有一个能被执行
5. 方法重载(overload)
多个方法有相同的名称,但参数列表不同
同一个方法名可以实现类似的多个功能
TIPS:
方法重载与下列因素有关:
【1】参数个数不同
【2】参数类型不同
【3】参数的多类型顺序不同
方法重载与下列因素无关:
【1】与参数名称无关
【2】与方法的返回值类型无关
06数组
1.概念
一种容器,可以同时存放多个数据值
2.特点
【1】是一种引用数据类型
【2】数组中的多个数据类型必须统一
【3】数组的长度在运行期间永不改变
3.数组的初始化
在内存中创建,并向其中赋予一些默认值
【1】动态初始化(指定长度)
//标准格式
数据类型[] 数组名称 = new 数据类型[数组长度];
//可拆分成两个步骤
数据类型[] 数组名称;
数组名称 = new 数据类型[数组长度];
【2】静态初始化(指定内容)
//标准格式
数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,...};
//可拆分成两个步骤
数据类型[] 数组名称;
数组名称 = new 数据类型[]{元素1,元素2,...};
//省略格式
数据类型[] 数组名称 = {元素1,元素2,...};
TIPS:
【1】虽然没说长度,但可以根据元素的个数得到长度
【2】静态初始化如果用省略模式就不能拆分成两个步骤
4.访问数组的元素进行获取
【1】若直接打印,得到的是数组对应的内存地址哈希值
【2】格式: 数组名称【索引值】
索引值:一个int代表数组中元素的编号
TIPS:
索引值从0开始,到(长度-1)为止
5.访问数组的元素进行赋值
使用动态初始化数组时,其中的元素将会自动拥有一个默认值规则如下
【1】整数类型:0
【2】浮点类型:0.0
【3】字符类型:’\u0000’
【4】布尔类型:false
【5】引用类型:null
TIPS:
静态初始化也有默认值的过程,只不过系统马上将默认值替换成大括号中的具体数值
6.获取数组的长度
【1】格式:数组名称.length
【2】得到int数字
【3】数组一旦创建,长度不可改变
7.数组的历遍输出&求最值&元素反转
使用循环
快捷键
数组名称.fori + Enter
8.数组作为方法的参数
数组可以作为方法的参数,当调用方法时,向方法小括号传参,传递进去的其实是数组的地址值
9.数组作为方法的返回值
【1】一个方法可以有多个参数, 但是只能有0或1个返回值,可以返回一个数组来返回多个返回值
【2】任何数据类型都能作为方法的参数类型,或者返回值类型
【3】数组作为返回值,返回的也是数组的地址值
07java中的内存划分
1.基本结构
java的内存有五个部分:
【1】栈(stack):存放的是方法中的局部变量,方法的运行一定要在栈中运行
局部变量:方法中的参数或{}中的内部变量
作用域:一旦超出作用域,立刻从栈中消失
【2】堆(heap):凡是new出来的东西都在堆中
堆内存里的东西都有一个地址:16进制
堆内存里面的数据,都有默认值,规则:
A.整数类型:0
B.浮点类型:0.0
C.字符类型:’\u0000’
D.布尔类型:false
E.引用类型:null
【3】方法区(method area):储存.class相关的信息,包含方法的信息
【4】本地方法栈(Native Method Stack):与操作系统相关
【5】寄存器(pc register):与cpu相关
2.数组的内存图
【1】两个数组的内存图
【2】两个引用指向同一个数组的内存图
3.常见问题
【1】数组索引越界异常
ArrayIndexOutOfBoundsException
原因:索引编号不存在
【2】空指针异常
NullPointerException
原因:数组需要new初始化才能使用其中的元素
如果只是赋值了一个null,没有进行new创建
08面向对象
1.概述
面向过程:当实现一个功能时,每一个具体的步骤都要亲力亲为,处理每个细节
面向对象:当实现一个功能时,不关心具体步骤而是找具有该功能的人,帮忙处理
2.类和对象
【1】类:一组相关属性和行为的集合,可看作是一类事物的模版
属性:该事物的状态信息
行为:该事物能够做什么
【2】对象:一类事物的具体体现,对象是类的一个实例
- 类是抽象的对一类事物的描述
- 对象是体力的是一类事物的实例
- 类是对象的模版,对象是类的实体
3.类的定义
【1】格式
public static ClassName {
//成员变量
//成员方法
}
成员变量:对应事物的属性
成员方法:对应事物的行为(去掉static)
4.对象的创建和使用
【1】导包:指出需要使用的类在什么位置
import 包名称.类名称
对于和当前类属于同一个包的情况,可以省略导包语句
【2】创建
//格式
类名称 对象名 = new 类名称();
【3】使用
A.使用成员变量:对象名.成员对象名
B.使用成员方法:对象名.成员方法名(参数)
TIPS:
如果成员变量没有赋值,将会有一个默认值,规则和数组一样
5.一个对象的内存图
成员方法保存的是一个地址值
6.两个对象使用同一个方法的内存图
7.两个引用指向同一个方法的内存图
8.使用对象类型作为方法的参数
9.使用对象类型作为方法的返回值
10.成员变量和局部变量的区别
【1】定义的位置【重点】
局部变量:在方法的内部
成员变量:在方法的外部,直接写在类之中
【2】作用的范围不一样【重点】
局部变量:只有在方法中可以使用
成员变量:整个类都可以用
【3】默认值不一样【重点】
局部变量:没有默认值,必须手动赋值
成员变量:如果没有默认值,会像数组一样自动赋默认值
【4】内存的位置不一样【了解】
局部变量:栈内存
成员变量:堆内存
【5】生命周期不一样【了解】
局部变量:随着方法进栈而诞生,方法出栈而消失
成员变量:随着对象创建而诞生,对象被垃圾回收而消失
11.面向对象的三大特征之封装
【1】封装:把一些细节信息隐藏起来,对外界不可见
A.方法就是一种封装
B.关键字private也是一种封
【2】继承
【3】多态
12.private关键字的作用以及使用
【1】无法阻止不合理的数据被设置进来,用private来解决
【2】使用private后,本类中依然可以随意访问,但超出本类范围之外就不能直接访问了
【3】间接访问private变量,定义一对getter,setter方法
【4】setter/getter命名规则:
getter:不能有参数,返回值类型和成员变量对应
setter:不能有返回值,参数类型和成员变量对应
13._this关键字的作用
【1】当局部变量和类的成员变量重名时,根据“就近原则”,优先使用局部变量
【2】如果需要访问本类当中的成员变量,需要使用格式:
this.成员变量名
【3】通过谁调用的方法,谁就是this
14.构造方法
构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实是在调用构造方法
【1】格式:
public 类名称(参数类型 参数名称) {
方法体
}
TIPS:
【1】构造方法的名称必须和类名称完全一样,就连大小写也要一样
【2】构造方法不要写返回值类型,连void都不写
【3】构造方法不能return一个具体的返回值
【4】如果没有任何构造方法,那么编译器会默认赠送一个构造方法,没有参数,方法体什么都不做
【5】一旦编写了至少一个构造方法,那么编译器将不再赠送
【6】构造方法也是可以进行重载的
重载:方法名称相同,参数列表不同
//全参构造方法
public Student(String name, int age){
this.name = name;
this.age = age;
}
Student stu = new Student(name:a, age:b);
15.标准的类
【1】所有成员变量都要使用private修饰
【2】为每一个成员变量编写一对getter/setter
【3】编写一个无参数的构造方法
【4】编写一个全参数的构造方法
这样的类也叫做java bean
快速创建方法:
【1】
【2】code->generate->getter and setter
【3】code->generate->constructor->select None
【4】code->generate->constructor->select all
快捷键:control+enter
09API应用程序编程接口
1.概述
现成可直接使用的类
2.Scanner
【1】功能:使用户能从System.in中读取一个数
【2】步骤:
(1)导包:
import 包名.类名
import java.util.Scanner;
若需要使用的目标类和当前类在同一个包下,则不用import
只有java.lang下的包不需要import
(2)创建(构造方法)
类名称 对象名 = new 类名称();
Scanner sc = new Scanner(System.in);
//System.in代表从键盘输入
(3)使用
对象名.成员方法名();
//从键盘获取一个int
int num = sc.nextInt();
//从键盘获取一个string
String sc = sc.next();
3.匿名对象
【1】创建对象的标准格式
类名称 对象名 = new 类名称;
【2】匿名对象只有右边的对象,没有左边的名字和赋值运算符
new 类名称;
TIPS:
匿名对象只能使用唯一的一次,下次再用不得不再创建一个新对象
new Person().name = a;
new Person().showName(); //结果:null
【3】匿名对象作为方法的参数和返回值
//匿名对象来进行传参
methodParam(new Scanner(System.in));
public static void methodParam(Scannner sc){
int num = sc.nextInt();
}
//匿名参数作为方法的返回值
public static Scanner(){
return new Scanner(System.in);
}
Scanner sc = methodReturn();
int num = sc.nextInt();
4.Random
【1】功能:用来生成随机数字
【2】步骤:
(1)导包:
import java.util.Random;
(2)创建
Random r = new Random();
//小括号中留空即可
(3)使用
对象名.成员方法名();
//获取一个随机的int数字(范围所有int,有正负)
int num = r.nextInt();
//获取一个随机的int数字(参数代表范围,左闭右开区间)[0,3)=0~2
int num = r.nextInt(3);
5.对象数组
【1】用来存储对象的数组
【2】储存的是对象的地址值
【3】缺点:一旦创建,长度不能改变
6.ArrayList集合
【1】区别:长度可以随意变化
【2】Class ArrayList
< E >:范型:装在集合中的所有元素都是统一的什么类型
范型只能是引用类型,不能是基本类型
【3】格式:
ArrayList<String> list=new ArrayList<>();
右侧 <> 中可以不写类型
【4】打印:
System.out.println(list); //[]
直接打印的不是地址值,而是内容[ ]
【5】常用方法
//添加数据,参数类型为范型,返回值为添加是否成功
//对Arraylist来说,一定成功,但对其他集合不一定
public boolean add(E e);
//获取元素,参数是索引编号,返回值是对应元素,索引值从0开始
public E get(int index);
//删除元素,参数是索引编号,返回值是删掉的元素,索引值从0开始
public E remove(int index);
//获取尺寸长度,返回值是元素的个数
public int size();
【6】遍历集合
使用for循环
【7】储存基本数据类型
如果希望储存基本类型,必须使用基本类型使用的包装类
基本类型 | 包装类(引用类型,在java.lang中) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
自动装箱,自动拆箱:基本类型和引用类型中的自动转换
7.字符串
【1】程序中所有双引号字符串,都是String类的对象(就算没有new,也是)
【2】特点:字符串是常量,一旦创建后永不可变【重点】
【3】因为不可改变,所以可以共享使用
【4】字符串效果上相当于char[]型字符数组,但是底层原理是byte[]字节数组
【5】创建字符串的常见3+1种方式
三种构造方法:
// 创建空白字符串,不含有任何内容
public String();
// 根据字符数组的内容,来创建对应的字符串
public String(char[] array);
char[] charArray = {'A','B','C'}
String str = new String(charArray); //ABC
// 根据字节数组的内容,来创建对应的字符串
public String(byte[] array);
一种直接创建:
String str = "Hello";
【6】字符串的常量池
只有用双引号直接创建就在字符串常量池中
= =对基本类型是数值的比较
= =对引用类型是【地址值】的比较
String str1 = "abc";
String str2 = "abc";
char[] charArray = {'a','b','c'};
String str3 = new String(charArray);
str1 == str2; //true
str1 == str3; //false
str2 == str3; //false
【7】常用方法
(1)比较
//==对象的地址值比较,参数可以是任何对象
//任何对象都可以用Object接收
// 只有参数是字符串并且内容相同才会返回true,否则返回false
// 不是比较地址值!!!
//如果双发一个常量一个变量,推荐把常量字符串写在前面
//原因:会出现空指针异常
public boolean equals(Object obj);
//忽略大小写
public boolean equalsIgnoreCase(Object obj);
(2)获取
//获取字符串长度(含有字符个数)
public int length();
//将当前字符串和参数字符串拼接成为返回值的新字符串
public String concat(String str);
//获取索引位置的单个字符(索引从0开始)
public char charAt(int index);
//查找参数字符串在本字符串中首次出现的索引位置,如果没有返回-1
public int indexOf(String str);
(3)截取
//从参数位置一直截取到字符串末尾,返回新字符串
public String substring(int index);
//从begin开始,一直到end结束,中间的字符串
//[begin,end)只包含左边,不包含右边
public String substring(int begin, int end);
//下面的写法字符串内容仍然没变:
//下面有两个字符串:"Hello","Java"
//str中保存的是地址值,地址值发生了改变
String str = "Hello";
String str = "Java";
(4)转换
//将当前字符串拆分为字符数组作为返回值
public char[] toCharArray();
//获得当前字符串底层的字符数组
public byte[] getBytes();
//将所有出现的老字符串替换成新的字符串,返回替换后的字符串
//CharSequence可以接收字符串类型
public String replace(CharSequence oldString, CharSequence newString)
String str = "How do you do?"
String str2 = str.replace("o","*") //H*w d* you d*?
(5)分割
//按照参数的规则,将字符串切分成若干部分
//参数其实是一个正则表达式。如果按照“.”进行区别,必须写"\\."
public String[] split(String regex);
8.static关键字
【1】背景:
- 对于姓名,年龄,学号,每个对象都有自己独立的数据
- 但对于所在教室,这应该是多个对象共享的同一份数据
【2】实现:
一旦用了static关键字,那么这样的内容不再属于对象自己,而是属于类的。所以凡是本类的对象,都共享同一份
【3】修饰成员变量
//student类中
static String room;
类名称.静态变量;
Student one = new Student();
Student two = new Student();
one.room = "1教室"
//two.room也变成“1教室”
【4】修饰成员方法(静态方法)
(1)静态方法不属于对象,是属于类的
(2)如果没有static,必须先创建对象再使用
(3)对于静态方法,可以通过对象名调用,也可以直接通过类名称调用
//Myclass是类名称
类名称.静态方法
Myclass.methodstatic();
//对于本类当中的静态方法,可以省略类名称
TIPS:
【1】静态不能访问非静态,只能访问静态
原因:内存中现有静态内容,后有的非静态内容
【2】静态方法中不能用this
原因:this代表当前对象,通过谁调用的方法,谁就是当前对象。但是静态和对象无关系
【5】静态的内存
【6】静态代码块
(1)格式:
public class 类名称 {
static {
//静态代码块内容
}
}
(2)特点:当第一次用到本类时,静态代码执行唯一的一次
(3)静态内容总是优先于非静态,所以静态代码块比构造方法先执行
(4)典型用途:用来一次性地对静态变量进行赋值
9.Arrays
【1】与数组相关的工具类,里面提供了大量的静态方法,用来实现数组常见的操作
【2】转换
//将参数数组变成字符串(按照默认格式:[元素1,元素2,...])
public static String toString(数组);
int []intArray = {10,20,30};
String intStr=Arrays.toString(intArray); //[10,20,30]
【3】排序
//按照默认升序(从小到大)对数组的元素进行排序
//如果是数组,sort默认按照升序(从小到大)
//如果是字符串,sort默认按照字母升序
//如果是自定义的类型,那么这个自定义类需要有Comparatable或者Comparator接口的支持
public static void sort(数组);
10.Math
【1】数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作
【2】常用方法:
//获取绝对值
public static double abs(double num);
//向上取整
public static double ceil(double num);
//向下取整
public static double floor(double num);
//四舍五入取整
public static double round(double num);
//Math.PI 是近似圆周率常量
10面向对象三大特征之继承
1.概述
【1】继承是多态的前提,如果没有继承,就没有多态
【2】继承主要解决的问题是共性抽取
【3】子类可以拥有父类的“内容”
【4】子类可以拥有自己的专属内容
2.格式
【1】关系: 子类就是一个(is-a)父类
【2】格式:
//父类格式:一个普通类的格式
public class 父类名称 {}
//子类格式
public class 子类名称 extends 父类名称{}
3.成员变量的访问特点
在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式:
【1】 直接:通过子类对象访问成员变量:
等号左边是谁就优先用谁,没有则向上找(创建对象时的左边)
到处都没有时,编译报错
【2】 间接:通过成员方法访问成员变量 :
看方法属于谁就优先用谁,没有则向上找
4.区分子类方法中重名的三种变量
【1】局部变量: 直接写成员变量名
【2】本类的成员变量: this.成员变量名
【3】父类的成员变量: super.成员变量名
5.继承中成员方法的访问特点
在父子类中有方法重名:创建的对象是谁,则优先用谁的方法
TIPS:
无论是成员变量还是方法,如果没有,一定是向上找父类的
6.方法的重写(override)
【1】概念:继承关系中,方法的名称和参数都一样
【2】重写和重载的区别
重写:名称一样,参数一样。覆盖,重写
重载:名称一样,参数不一样
【3】特点:创建的是子类对象则优先用子类方法
TIPS:
【1】安全检测
//注解:写在方法前面,用来检测是不是正确的有效覆盖
//注解可写可不写
@override
【2】子类方法返回值必须小于等于父类方法返回值范围
Object类是所有类的公共最高父类(祖宗类)
【3】子类方法的权限必须大于等于父类方法的权限修饰符
public>protected>(default)>private
default不是关键字而是什么都不写留空
设计原则:对于已经使用投入的类,尽量不要修改老的,推荐定义一个新的类,来重复利用其中共性内容,并且添加改动新内容(继承)
// 重写方法:使用重写的父类方法
super.方法名(参数);
7.继承中父子类构造方法的访问特点
【1】子类构造方法中有一个默认隐藏的"super()"的调用。所以一定是先调用父类构造,然后调用子类构造
【2】子类构造可以通过super关键字来调用父类重载构造
【3】super的父类构造调用必须是子类构造方法的第一句。不能一个子类构造调用多次super构造
(总结):子类构造方法必须调用父类构造方法,不写则赠送super();写了则用写的指定的super调用,super只能有一个,还必须是第一个
8.继承的三个特点
【1】java是单继承:只能有一个父类
假设能够多继承,两个父类中都有method()方法,子类不知道调用哪个父类的method()方法
【2】java可以多级继承(有爷爷):A也算是C的父类,但不能算是直接父类
【3】一个子类的直接父类是唯一的,但是一个父类可以拥有多个子类
11super&this关键字总结
super关键字用来访问父类的内容
this关键字用来访问本类的内容
1.super关键字的三种用法
【1】子类成员方法中访问父类的成员变量
【2】子类成员方法中访问父类的成员方法
【3】子类构造方法中访问父类的构造方法
2.this关键字的三种用法
【1】本类成员方法中访问本类的成员变量
【2】本类成员方法中访问本类的另一个成员方法
【3】本类构造方法中访问本类的另一个构造方法
A.在第三种用法中要注意:this(…)调用也必须是构造方法的第一个语句
B.super和this两种构造调用不能同时使用
3.图解
12抽象
1.概述:
抽象方法:如果父类当中的方法不确定如何进行{}方法体实现,那么这是一个抽象的方法
2.格式:
//抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束
//抽象类:抽象方法所在的类必须是抽象类,在class前加上abstrac
public abstract class Animal {
public abstract void eat();
}
3.如何使用抽象类和抽象方法
【1】不能直接创建new抽象类对象
【2】必须用一个子类来继承抽象父类
子类必须覆盖重写(实现)父类当中所有的抽象方法
实现:去掉抽象方法的abstract,然后补上方法体大括号
@overrid e
public class Cat extends Animal{
public void eat() {
sout(猫吃鱼);
}
}
4.创建子类对象进行使用
TIPS:
【1】不能直接创建对象
【2】抽象类可以有构造方法,提供子类创建对象时,初始化父类成员时使用的
【3】抽象类中,不一定有抽象方法,但有抽象方法的类一定是抽象类
【4】子类必须覆盖重写所有抽象方法,除非子类也是抽象类
13接口
1.概述和生活例子
【1】电源插座中的电源接口:
接口是一种公共的规范标准,只要符合规范标准,大家都可以通用
【2】USB接口:
只要符合USB接口的规范,各种设备都能使用
2.基本定义格式
【1】接口是多个累的公共规范
【2】接口是一种引用数据类型,最重要的内容就是其中的抽象方法
【3】格式:
public interface 接口名称{
//接口内容
}
//备注:换成关键字interface之后还是.java->.class
//接口中可以有的内容是:
//java7
//1.常量
//2.抽象方法
//java8
//3.默认方法
//4.静态方法
//java9
//5.私有方法
3.抽象方法的定义
public abstract 返回值类型 方法名称(参数列表);
TIPS:
【1】接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract
【2】这两个关键字修饰符,可以选择性地省略
【3】方法的三要素可以随意定义
4.抽象方法的使用
【1】接口不能直接使用,必须有一个“实现”类来“实现”接口
public class 实现类名称 implements 接口类名称{
// ...
}
【2】接口的实现类必须覆盖重写(实现)接口中所有的抽象方法
【3】创建实现类的对象,进行使用
TIPS:
如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类
5.默认方法的定义
格式
public default 返回值类型 方法名称(参数列表){
方法体
}
//备注:接口中的默认方法,可以解决接口升级的问题
6.默认方法的使用
public default void methodDefault(){}
【1】接口的默认方法可以通过接口实现类对象直接调用
【2】接口的默认方法也可以通过接口实现类进行覆盖重写
7.静态方法的定义
格式:
public static 返回值类型 方法名称(参数列表) {
//方法体
}
8.静态方法的使用
【1】不能通过接口实现类对象来调用接口中的静态方法
【2】应该通过接口名称直接调用其中的静态方法
【3】格式
接口名称.静态方法名称(参数列表) ;
9.私有方法的定义&使用(java9)
【1】需要抽取一个公共方法来解决两个方法之间重复代码的问题,但是这个公共方法 不应该让实现类使用,应该私有化
【2】解决方法:
(1)普通私有方法:解决多个方法之间重复代码问题
private 返回值类型 方法名称(参数列表){
//方法体
}
(2)静态私有方法:解决多个静态方法之间重复代码问题
private static 返回值类型 方法名称(参数列表){
//方法体
}
10.常量的定义&使用
【1】接口当中也可以定义“成员变量”,但是必须使用public static final 三个关键字进行修饰
【2】从效果上看,这其实就是接口的常量
【3】格式
public static final 数据类型 常量名称 = 数据值;
【4】一旦使用final关键字修饰,代表不可改变
TIPS:
【1】接口中的常量可以省略三个关键字,但会自动帮你加上
【2】接口中的常量必须进行赋值,不能不赋值
【3】接口中常量名称全使用大写,下划线分割单词(命名规则)
11.使用接口时注意事项
【1】没有静态代码块或者构造方法的。
【2】一个类的直接父类是唯一的,但是一个类可以同时实现多个接口
public class MyInterfaceImpl implements MyInterfaceA,MyInterfaceB {
//覆盖重写所有抽象方法
}
【3】如果实现的类所实现的多个接口中,存在重复的抽象方法,那么只需要重写一次即可
【4】如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类
【5】如果实现类所实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写
【6】一个类如果直接父类中的方法和接口中的默认方法冲突,优先用父类当中的方法
12.接口之间的多继承
【1】类与类之间是单继承的,直接父类只有一个
【2】类与接口之间是多实现的,一个类可以实现多个接口
【3】接口与接口之间是多继承的
TIPS:
【1】多个父接口中的抽象方法如果重复没关系
【2】多个父接口中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,而且要带着default关键字
10面向对象三大特征之多态(polymorphism)
1.概述
extends继承或implements实现,是多态性的前提
一个对象拥有多种形态就是对象的多态性
2.格式与使用
【1】父类引用指向子类对象
【2】格式:
父类名称 对象名 = new 子类名称();
接口名称 对象名 = new 实现类名称();
//左侧父类的引用,指向了右侧子类的对象
Fu obj = new Zi();
obj.method(); //子类方法
3.多态中成员变量的使用特点
【1】和继承没有区别
【2】访问有两种方式:
A. 直接:通过对象名称访问成员变量:
等号左边是谁就优先用谁,没有则向上找(创建对象时的左边)
到处都没有时,编译报错
B.间接:通过成员方法访问成员变量 :
看方法属于谁就优先用谁,没有则向上找
子类没覆盖重写就是子
子类覆盖重写就是父
【3】编译看左边,运行还看左边
4.多态中成员方法的使用特点
【1】看new的是谁就优先用谁,没有则向上找
【2】编译看左边,运行看右边
编译看左边:左边是Fu,Fu当中没有methodZi方法,编译报错
5.多态的好处
6.对象的向上转型
【1】向上转型,就是对象的写法
【2】格式
父类名称 对象名 = new 子类名称();
【3】含义:右侧创建了一个子类对象,把它当作父类来看待
TIPS:
向上转型一定是安全的:从小范围转向大范围
7.对象的向下转型
【1】向上转型的弊端:
无法调用子类原本特有的方法
【2】解决方案:用对象的向下转型【还原的动作】
【3】格式:
子类名称 对象名 = (子类名称)父类对象;
【4】含义:将父类对象,还原成本来的子类对象
TIPS:
【1】保证对象创建的时候是什么,向下转型才能还原成什么
【2】如果对象创建时候是另一类,向下转型成这一类就会报错(ClassCastException)
8.Instanceof
【1】如何知道父类引用的对象是什么子类
【2】格式
//会得到一个boolean值结果
//也就是判断前面的对象能不能当作后面类型的实例
对象 instanceof 类型
11final关键字
含义:最终的,不可改变的
1.用法
【1】修饰类
【2】修饰方法
【3】修饰局部变量
【4】修饰成员变量
2.用来修饰一个类
【1】格式
public final class 类名称 {
//...
}
【2】含义:当前这个类不能有任何的子类,不能被作为父类
【3】一个类如果是final的,那其中的所有成员方法都不能被覆盖重写(因为没有子类)
3.用来修饰一个方法
【1】格式
修饰符 final 返回值类型 方法名称(参数列表) {
//方法体
}
【2】含义:这个方法就是最终方法,不能被覆盖重写
TIPS:
对于类,方法来说,abstract关键字和final关键字不能同时使用,因为矛盾
4.用来修饰一个局部变量
【1】一旦使用final来修饰局部变量,那么这个变量就不能发生改变 “一次赋值,终生不变”
【2】对基本数据类型,是变量中的数据不可改变
【3】对引用数据类型,是变量中的地址值不可改变(可以用setter来改变数据)
5.用来修饰一个成员变量
【1】对于成员变量来说,使用final关键字修饰,那么这个变量也是不可改变的
【2】由于成员变量具有默认值,所有用了final之后必须手动赋值,不会给默认值了
【3】对于final的成员变量,要么直接赋值,要么通过构造方法赋值(二者选其一)
【4】使用构造方法赋值时,必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值
12四种权限修饰符 & 内部类
1.四种权限修饰符
public > protected > (default) > private
同一个类
✓
\checkmark
✓
✓
\checkmark
✓
✓
\checkmark
✓
✓
\checkmark
✓
同一个包
✓
\checkmark
✓
✓
\checkmark
✓
✓
\checkmark
✓
×
\times
×
不同包子类
✓
\checkmark
✓
✓
\checkmark
✓
×
\times
×
×
\times
×
不同包非子类
✓
\checkmark
✓
×
\times
×
×
\times
×
×
\times
×
2.内部类
【1】概念:如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类
【2】分类:
(1)成员内部类
(2)局部内部类(包含匿名内部类)
3.成员内部类
【1】格式
修饰符 class 外部类名称 {
修饰符 class 内部类名称 {
//...
}
//...
}
【2】注意:内用外,随意访问;外用内,一定要借助内部类对象
【3】使用:
(1)间接方式:在外部类的方法中,使用内部类;然后main只是调用外部类的方法
(2)直接方式:公式:
类名称 对象名 = new 类名称();
外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
【4】同名变量的访问
(1)如果出现重名现象格式是:
外部类名称.this.外部类成员变量名
4.局部内部类
【1】如果一个类定义在一个方法内部的,那么这个类就是一个局部内部类。
【2】“局部”:只有当前方法才能使用它,出了这个方法外就不能用了
【3】格式
修饰符 class 外部类名称 {
修饰符 返回值类型 外部类方法名称(参数列表){
class 局部内部类名称 {
// ...
}
}
}
【4】final问题
局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】
原因:
(1)new的对象在堆内存当中
(2)但局部变量跟着方法走,在栈内存中
(3)方法运行结束后,立刻出栈,局部变量就会立刻消失
(4)new的对象会在堆中持续存在,直到垃圾回收为止
TIPS:
从java8开始,只要局部变量事实不变,那么final关键字可以省略
5.权限修饰符规则
【1】外部类:public/(default)
【2】成员内部类:都可以
【3】局部内部类:什么都不能写,和(defult)不同
6.匿名内部类
【1】如果接口的实现类(或者父类的子类)只需要使用唯一的一次,那么这种情况下,就可以省略掉该类的定义,改为使用匿名内部类
【2】格式
接口名称 对象名 = new 接口名称() {
// 覆盖重写接口中所有抽象方法
};
TIPS:
【1】格式的解析:
(1)new代表创建对象的动作
(2)接口名称是匿名内部类需要实现哪个接口
(3){…}是匿名内部类的内容
【2】匿名内部类,在【创建对象】时,只能使用唯一的一次
如果希望多次创建对象,而且类的内容一样时,那么就必须使用单独定义的实现类
【3】匿名对象,在调用方法时,只能调用唯一的一次
如果希望同一个对象,调用多次方法,那么必须给对象起一个名字
【4】匿名内部类是省略了实现类(子类)
匿名对象是省略了对象的名称
这两是不是同一个东西!
7.接口作为成员变量类型
//1.使用单独定义的实现类,匿名对象
hero.setskill(new SkillImpl());
//2.使用匿名内部类
Skill skill = new Skill(){
@override
public void use(){}
};
hero.setskill(skill);
//3.同时使用匿名对象和匿名内部类
hero.setskill(new Skill(){
@override
public void use(){}
}) ;
8.接口作为参数和返回值
java.util.List是ArrayList所实现的接口