0%

一.BigInteger类
BigInteger类
java.math.BigInteger类,用于大整数计算(理论上整数位数是不受限制的)

BigInteger的构造方法

1
public BigInteger(String num);//创建一个大整数
BigInteger的成员方法
BigInteger不能直接使用+-*/进行计算,而是要通过方法进行计算

1
2
3
4
public BigInteger add(BigInteger value);//求和
public BigInteger subtract(BigInteger value);//求差
public BigInteger multiply(BigInteger value);//求积
public BigInteger divide(BigInteger value);//求商

二.BigDecimal类
使用基本类型会出现精度差
计算机计算小数时,总是存在不精确的情况

BigDecimal类的介绍
提供了算数、缩放操作、舍入、比较、散列和格式转换的操作。提供了更加精确的数据计算方式。

BigDecimal的构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
public BigDecimal(double d);
public BigDecimal(String d);[推荐]

//BigDecimal的成员方法
public BigDecimal add(BigDecimal value);//求和
public BigDecimal subtract(BigDecimal value);//求差
public BigDecimal multiply(BigDecimal value);//求积
public BigDecimal divide(BigDecimal value);//求商(能除尽)
//注意:如果除不尽,会抛出异常java.lang.ArithmeticException
//此时,可以使用另一个divide方法的重载
public BigDecimal divide(BigDecimal value,int 保留位数,oundingMode.roundingMode);
//范例
BigDecimal divide = bd1.divide(new BigDecimal("0.3"), 5, RoundingMode.HALF_UP);

三.Array类
3.1 Arrays类的介绍
Arrarys是专门操作数组的工具类(方法都是静态的)

工具类的设计思想:
•构造方法用private修饰
•成员用public static修饰

3.2 Array类的常用方法

方法名 说明
public static void sort(int[] a); 对数组进行从小到大的排序
public static String toString(int[] a); 将一个数组的元素拼成一个大的字符串
extend:
sort方法对于数值类型的数组排序时,按照数值的从小到大进行排序。
sort方法对于char类型的数组排序时,按照字符码值的从小到大进行排序。
sort方法对于String类型的数组排序时,首先比较首字母的码值,如果相等,再比较次字母的码值,依次类推,从小到大进行排序。

四.包装类
4.1 包装类的作用
Java提供了两个类型,基本类型和引用类型,基本类型效率高,但是引用类型可操作性高,把基本类型包装成引用类型,就是包装类。
包装类就是基本类型对应的引用类型,全称叫基本数据类型的包装类(简称包装类)

基本类型包装类概述:将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据
常用操作之一:用于基本数据类型与字符串之间的转换

基本类型 引用类型
byte Byte
short Short
*char Character
*int Integer
long Long
float Float
double Double
boolean Boolean
4.2 Integer包装类介绍
Integer是int基本类型的包装类

4.3 Integer类的构造方法和静态方法
构造方法:

1
2
public Integer(int value);//过时
public Integer(String value);//过时
静态方法:

方法名 说明
public static Integer valueof(int value); 返回表示指定的int值类型的Integer实例
public static Integer valueof(String value); 返回一个保存指定值的Integer对象String
范例:

1
2
3
4
5
6
7
8
9
10
11
12
Integer i1 = new Integer(10);
System.out.println(i1);

Integer i2 = new Integer("11");
System.out.println(i2);

Integer i3 = Integer.valueOf(12);
System.out.println(i3);

Integer i4 = Integer.valueOf("13");
System.out.println(i4);

4.4.1 拆箱和装箱
基本类型和对应的包装类是可以相互转换的。

装箱:把基本类型———转换成————>对应包装类
拆箱:包装类———转换成————>对应的基本类型

例如:

1
2
3
4
5
6
//装箱操作
Integer i1 = new Integer(10);
Integer i3 = Integer.valueOf(12);

//拆箱操作
int value = i1.intValue();

4.4.2 自动拆箱和装箱*[JDK 5中引入该操作]

1
2
3
Integer i =4//底层已经调用Integer.valueOf()方法自动帮助进行装箱操作

int value = i;//底层调用i.intValue()自动帮助我们进行拆箱操作

注意:在使用保证类类型时,如果做操作,最好先判断是否为null
推荐:只要是对象,在使用前将必须进行不为null的判断

题:
Integer a = 10;//装一次
a++;//拆一次 装一次
自动装箱2次
自动拆箱1次

4.5 基本类型与字符串之间的转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
•基本类型转换成String

int num = 10

a.直接加一个" "
String s = num + " ";

b.通过String的静态方法valueOf
String s = String.valueof(num);
•String转换成基本类型
String num = "100";
方式一:
a.
先使用Integer的构造方法
Integer i = new Integer(num);
b.
接着拆箱调用intValue方法拆箱
int number = i.intValue();
或不调用intValue方法自动拆箱接口
int number = i
方式二:
直接调用包装类的parseXxx(String s)解析字符串方法
int number = Integer.parseInt(num);
•字符串无法解析成基本类型失败时的异常
Exception in thread "main" java.lang.NumberFormatException

五.String类常用方法
String的构造方法:
直接赋值:
String s = “java”;
构造方法:
String s = new String(“java’);

char[] chs = {“j”,”a”,”v”,”a”};
String s = new String(chs);

byte[] bs = {97,98,99,100};
String s = new String(bs);//最终结果是ASCII码对应的字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public static void main(String[] args) {
String s = "Hello,World";
//1.concat 拼接
String s1 = s.concat("+Java");
System.out.println(s1);//Hello,World+Java

//contains 判断是否包含某个小字符串
boolean b1 = s.contains("o");
boolean b2 = s.contains("world");
System.out.println(b1);//true
System.out.println(b2);//false

//endswith 是否以该字符结尾
boolean b3 = s.endsWith("ld");
boolean b4 = s.endsWith("lo");
System.out.println(b3);//true
System.out.println(b4);//false

//startwith 是否以该字符开头
boolean b5 = s.startsWith("He");
boolean b6 = s.startsWith("Wo");
System.out.println(b5);//true
System.out.println(b6);//false


//indexOf查找目标字符串在当前字符串第一次出现的索引
int index1 = s.indexOf("o");
System.out.println(index1);//4
int php = s.indexOf("php");
System.out.println(php);// -1

//lastdexOf查找目标字符串在当前字符串最后一次出现的索引
int index2 = s.lastIndexOf("o");
System.out.println(index2);//7
int delphi = s.lastIndexOf("delphi");
System.out.println(delphi);// -1

//replace 将当前字符串中的目标字符串替换为另外一个字符串
String replace = s.replace("Hello", "Halo");
System.out.println(replace);//Halo,World
String replace1 = s.replace("php", "Halo");
System.out.println(replace1);//Hello,World

//substring 指定
String subs = s.substring(2);
System.out.println(subs);//llo,World
String subs1 = s.substring(2,5);
System.out.println(subs1);//llo,截取到5之前,不包含5

//toCharArry 将字符转换成char Array
char[] chs = s.toCharArray();
System.out.println(chs);//Hello,World
System.out.println(Arrays.toString(chs));//[H, e, l, l, o, ,, W, o, r, l, d]

//toLowerArry 转成小写
String s2 = s.toLowerCase();
System.out.println(s2);//hello,world

//toUpperArry 转成大写
String s3 = s.toUpperCase();
System.out.println(s3);//HELLO,WORLD


String ss = " Hello ,World ";
//trim 去除字符串两端的空格
String trim = ss.trim();
System.out.println(trim);//Hello ,World


String sss = "a,b,c,d,e,f";
//split 切割字符串
String[] split = sss.split(",",7);
String s4 = Arrays.toString(split);
System.out.println(s4);//[a, b, c, d, e, f]
System.out.println(split[0]);//a
System.out.println(split[1]);//b
System.out.println(split[2]);//c
System.out.println(split[3]);//d
System.out.println(split[4]);//e
System.out.println(split[5]);//f
}

六.引用类型使用小结
6.1 类名作为方法参数和返回值
主要是(类,抽象类,接口,以及多态)复习

基本类型:

1
2
3
4
5
6
public void show(int a){

}
public int method(){

}

普通类,也可以作为方法的参数和返回

1
2
3
4
5
6
public void show(Dog g){

}
public Dog method{

}

抽象类,也可以作为方法的参数和返回

1
2
3
4
5
6
public void show(Animal a){
//Animal a = 任意一个子类对象
}
public Animal method{

}

接口,也可以作为方法的参数和返回

1
2
3
4
5
6
public void show(Flyable a){
//Flyable f = 该接口的任意一个实现类对象
}
public Flyable method(){

}

总结:
a.当基本类型作为方法的参数和返回值时,调用方法和返回数据时,返回该基本类型的值即可
b.当引用类型作为方法的参数和返回值时,调用方法和返回数据时,返回该引用类型的对象/子类对象/实现类对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
killPerson(new Person(18,"a"));
Person pp = birthPerson();
System.out.println(pp);
}
public static void killPerson(Person p){
System.out.println("ppp");
System.out.println(p);

}

public static Person birthPerson() {
return new Person(3,"bbb");

}

总结:当方法的参数或者返回值是普通类时,我们要传入或返回对象的是该类的对象

6.2 抽象类作为方法参数和返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
show(new Dog());
show(new Cat());
Animal an = BirthAnimal();
an.eat();
an.bark();
}
public static void show(Animal an){
an.eat();
an.bark();
}
public static Animal BirthAnimal(){
// return new Dog();
return new Cat();
}

总结:当方法的参数或者返回值是抽象类时,我们要传入或返回对象的是该类的子类对象

6.3 接口作为方法参数和返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
showFly(new Bird());
showFly(new Plane());
Flyable fa = getfly();
fa.fly();
}
//定义方法,使用Flyable接口
public static void showFly(Flyable fa){
fa.fly();
}
public static Flyable getfly(){
// return new Plane();
return new Bird();
}

总结:当方法的参数或者返回值是接口时,我们要传入或返回对象的是该类的实现类对象

6.4 类名作为成员变量的,其实引用类型也可以作为类的成员变量

1
2
3
4
5
6
7
public class Student{
int age;
String name;
Dog dog;
Animal an;
Flyable fa;
}

总结:当普通类作为成员变量,给该成员变量赋值时,赋值普通类的对象
6.5 抽象类作为成员变量

1
2
3
4
5
6
7
8
9
10
11
12
public class Student {
int age;
String name;
Animal an;
}
public static void main(String[] args) {
Student ss =new Student();
ss.age = 1;
ss.name = "s";
ss.an = new Dog();

}

总结:当抽象类作为成员变量时,当给该成员变量赋值,赋值给该成员类的子类对象

6.6接口作为成员变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Student {
private int age;
private String name;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Flyable getFa() {
return fa;
}

public void setFa(Flyable fa) {
this.fa = fa;
}

private Flyable fa;
}

public class TestDemo11 {
public static void main(String[] args) {
Student ss = new Student();
ss.setAge(1);
ss.setName("a");
ss.setFa(new Bird());

}
}

总结:当接口作为成员变量时,当给该成员变量赋值,赋值给该成员类的实现类对象

总结
1.BigInteger
2.BigDecimal
add subtract multiply divide

3.Arrays工具类*
public static void sort(int[] arr);默认对数组进行升序排序
public static String toString(int[] arr);将数组的所有元素拼在一起成一个大字符串返回

4.包装类*
a.八种基本类型对应的引用类型
b.装箱和拆箱(JDK5之后,自动拆装箱)
Integer i = 10;
int j =1;

5.String **
构造方法和常用的13个成员方法

6.引用类型的使用总结
引用类型作为方法的参数和返回值
引用类型作为成员变量

如果引用类型是普通类,那么用到该普通类的普通类对象
如果引用类型是抽象类,那么用到该抽象类的子类对象
如果引用类型是接口,那么用到该接口的实现类对象

一. Object类
1.1 Object介绍
Object类是所有类的父类,所有对象(包括数组)都具有该类中的11种方法。

构造方法:
public Object();

为什么之前说子类的构造方法默认访问的是父类的无参构造方法,因为它们的顶级父类只有无参构造方法

如果一个类我们没有指定其父类,那么默认继承Object

1
2
public class Dog /*extends Object*/{
}

1.2 toString方法
作用:返回该对象的字符串表示(调用的对象)
默认字符串表示的形式:
包名.类名@地址值
com.test.Demo01.Dog@61bbe9ba

在实际开发中,我们通常会重写toString方法,将本类返回的地址值改回返回对象的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public String toString() {
return "Dog{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}

public static void main(String[] args) {
Dog dd = new Dog(10,"a");
String ss = dd.toString();
System.out.println(ss);
}

Dog{age=10, name=’a’}
Dog{age=20, name=’b’}

注意:重写toString方法之后,当调用对象的toString方法时,返回的不再是地址值,而是具体的属性值。
实际上,不需要手动调用toString方法,可以简写为:

1
2
Dog d = new Dog();
System.out.println(d);

打印变量d,会自动调用d.toString(),其实就是打印toString方法值的返回值

总结:

1
2
3
System.out.println(ss2.toString());
//等同于
System.out.println(ss2);

1.3 equals方法
作用:判断其他对象是否是此对象“相等”。
默认比较的是两个对象的地址值
equals源码:

1
2
3
public boolean equals(Object obj) {
return (this == obj);
}

在实际开发中, 也会重写equals方法,将本来的比较地址值改为比较内容(属性值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public boolean equals(Object o) {
//合法性判断
/*
this --- age1
o --- age2
*/
//比较地址是否相同
if (this == o) return true;
//判断参数是否为null
//getClass判断是否来自同一个类(对比字节码Class文件)
if (o == null || getClass() != o.getClass()) return false;
//向下转型
Cat cat = (Cat) o;
//判断时,必须当前对象的age和比较对象的age相同,切当前name和比较对象name相同,才返回true
return age == cat.age &&
Objects.equals(name, cat.name);
}

方法名 说明
public String toString(); 返回对象的字符串形式表示。建议所有子类重写该方法,IDE自动生成
public boolean equals(Object obj); 比较对象是否相等,默认比较地址,重写可以比较内容,IDE自动生成
1.4 native本地方法
有native修饰的方法,称为本地方法,不是用Java写的,是使用底层C/C++写的。

1
public native int hashCode()

1.5 扩展(equals和==的区别)
对于基本类型:
== 比较的是数值
没有equals方法
对于引用类型:
== 比较的是地址值
equals默认情况下比较的是地址值,@override后,就按照重写的比较规则比较(一般比较属性值)

1.6 Objects类
Objects类,称之为工具类(内部所有的方法都是静态的)
在Objects中有一个方法:
public static boolean equals(Object a, Object b);
用于判断两个对象是否“相等”,并避免类空指针异常,该方法源码如下:

1
2
3
public static boolean equals(Object a, Object b){
return( a == b ) || ( a != null && a.equals(b));
}

二. Date 类
2.1 Date类的介绍
包:java.util.Date
作用:代表某一个时间点,可以精确到毫秒

2.2 Date类的构造方法

方法名 说明
public Date(); 创建一个Date对象,并初始化,代表当前的系统时间,精确到毫秒。
public Date(long date); 创建一个Date对象,代表距离国际基准设计millis后的时间。
2.3 Date类的常用方法

方法名 说明
public void getTime(); 获取当前Date对象距离基准时间(1910-1-1 00:00:00)的毫秒值。
public void setTime(long date); 设置时间,修改当前Date对象距离基准时间的毫秒值
三. DateFormat类
3.1 DateFormat类的作用
让时间/日期和具体的文本直接来回转换

SimpleDateFormat是一个具体的类,用于以区域设置敏感的方式格式化和解析日前。

日前和时间格式由日期和时间模式字符串指定,在日期和时间模式字符串中,从’A’到’Z’以及从’a’到’z’引号的字母被解释为表示日期或时间字符串的组件的模式字母

格式化:将 Date对象 转成具体的 时间文本字符串
解析:将 时间字符串 转回 Date对象

3.2 DateFormat类的构造方法
DateFormat is an abstract class for date/time

DateFromat是抽象类,使用其子类(SimpleDateFormat)
public SimpleDateFormat(String pattern,
DateFormatSymbols formatSymbols);
这里的pattern表示我们想要的时间字符串格式/模式

方法名 说明
public SimpleDateFormat(); 构造一个SimpleDateFormat,使用默认模式和日期格式
public SimpleDateFormat(String pattern); 构造一个SimpleDateFormat使用给定的模式和默认的日期格式
Letter Date or Time Component Presentation Examples
G Era designator Text AD
y Year Year 1996; 96
Y Week year Year 2009; 09
M Month in year (context sensitive) Month July; Jul; 07
L Month in year (standalone form) Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day name in week Text Tuesday; Tue
u Day number of week (1 = Monday, …, 7 = Sunday) Number 1
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08; -0800; -08:00
主要:
y – 年
M – 月
d – 日
H – 时
m – 分
s – 秒

3.3 DateFormat类的成员方法

方法名 说明
public String format(Date date); 格式化方法,将日期格式化成日期/时间字符串
public Date parse(String date); 解析方法,从给定字符串的开始解析文本以及生成日期

1
2
3
4
5
6
7
8
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date now = new Date();
String nowStr = sdf.format(now);
System.out.println(nowStr);
Date date = sdf.parse("2020年04月07日 11:18:09");
System.out.println(date);
}

四. Calendar类
4.1 Calendar的介绍和获取对象方式:
概述:
Calendar为某一时刻和一组日历字段直接的转换提供了一些方法,并为操作日历字段提供了一些方法

作用:表示某个时间点
获取对象的方式:
创建其子类GregorianCalendar类的对象(目前不使用)

使用Calendar的静态方法【推荐方式】:
Calendar c = Calendar.getInstance();创建一个子类对象,返回

注意:在Calendar类中,月份(0-11),代表我们的(1-12)

4.2 Calendar类中常见的方法

方法名 说明
public int get(int field); 返回给定日历字段的值
public abstract void add(int field,int amount); 根据日历的规则,将指定的时间量添加或减去给定的日历字段
public final void set(int year,int month,int date); 设置当前的日历年月日

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static void main(String[] args) {
//获取一个Calendar对象
Calendar c = Calendar.getInstance();//多态形式
System.out.println(c);
//获取Calendar对象中的某个数值
int year = c.get(Calendar.YEAR);
System.out.println("Year:"+year);

int month = c.get(Calendar.MONTH );
System.out.println("Month: "+month);

int day = c.get(Calendar.DAY_OF_MONTH);
System.out.println("Day: "+day);
}

public static void main(String[] args) {
//获取一个Calendar对象
Calendar c = Calendar.getInstance();
System.out.println(c);
//修改Calendar对象中某个成员的值
c.set(Calendar.YEAR,3000);
c.set(Calendar.MONTH,3);
c.set(Calendar.DAY_OF_MONTH,20);
print(c);
//增加Calendar对象中某个成员的值
c.add(Calendar.YEAR,20);
c.add(Calendar.MONTH,3);
c.add(Calendar.DAY_OF_MONTH,20);
print(c);
}

注意:
a.Calender类中,month从0-11,我们是1-12
b.时间日期,也有大小之分,时间越靠后,我们认为其越大

五. Math类
5.1 Math类的介绍
Math中主要包含了一些数学运算相关的方法
Math类中这些方法都是静态的(通过类名就可以直接调用,Math当作一个工具类)

5.2 常用方法

1
2
3
4
5
6
7
8
9
10
public static double abs(double d);//求绝对值
public static double ceil(double d);//向上取整
public static double floor(double d);//向下取整
public static int round(float d);//四舍五入到整数

public static int max(int a,int b);//返回两个int值中的较大值
public static int min(int a,int b);//返回两个int值中的较小值
public static double pow(double a,double b);//求次幂,返回a的b次幂的值

public static double random();//返回值为double的正值,[0.0,1.0]

注意:
ceil只要有小数部分不是0,就向整数位进1
floor无论如何,小数部分不要,只要整数部分
Math.ceil(3.0);==> 3.0
Math.floor(3.0);==> 3.0

六. System
6.1 System类的介绍
The System class contains several useful class fields and methods. It cannot be instantiated.
System类中包含几个静态到变量和静态到方法,且该类不能被实例化(无法被创建对象)

方法名 说明
public static void exit(int status); 终止当前运行的Java虚拟机,非0表示异常终止
public static long currentTimeMillis(); 返回当前时间(以毫秒为单位)
System源码表示构造被私有化,故而无法创建对象
源码:

1
2
3
/** Don't let anyone instantiate this class */
private System() {
}

6.2 System类到常见用法

1
public static void exit(int status);
作用:退出Java虚拟机

1
public static long currentTimeMillis()
作用:获取当前系统毫秒值

1
2
3
4
5
6
7
8
9
10
long start_new = System.currentTimeMillis();

StringBuilder s1 = new StringBuilder();
for (int i = 0; i < 5000; i++) {
s1.append(i);
}

long end_new = System.currentTimeMillis();

System.out.println("time:"+(end_new-start_new));

总结:
1.Object:所有类的父类
toString:默认返回的字符串表示,包名.类名@地址名
开发中一般会重写toString,返回对象的内容(command+n自动生成)
注意:实际上不需要手动调用toString方法,因为在使用对象时,编译器会自动调用toString()方法

equals默认比较的是两个对象的地址值,在开发中一般会@override,比较两个对象的内容(属性值)

2.Date & DateFormat

构造方法:
public Date();//当前系统时间
public Date(long millins);//距离基准时间millis毫秒后的时间

成员方法:
public long getTime();//获取当前Date对象距离基准时间的毫秒值
public long setTime(long millins);//设置当前Date对象距离基准时间的毫秒值

SimpleDateFormat<子类> extends DateFormat<抽象类>
构造方法:
public SimpleDateFormat(String 模式/格式);//“yyyy-MM-dd HH:mm:ss”

成员方法:
格式化:
public String format(Date date);
解析:
public Date parse(String time);

3.Calendar
获取对象:
Calendar c = Calendar.getinstance();//返回Calendar的子类对象
成员方法:
public void get(int field);
public void set(int field,int value);
public void add(int field,int value);

4.Math
Math类中方法都是静态的
public static double abs(double d);
public static double ceil(double d);
public static double floor(double d);
public static double rount(double d);
public static double pow(double d);

5.System
System类中方法都是静态的
public static void exit(0);//退出JVM
public static long currentTimeMills();//获取当前时间的毫秒值(用于计算某段代码的运行时间)

一. 多态
面向对象三大特征:封装,继承,多态
1.1 多态定义:
a.严格的定义:同一个动作,具有不同的表现形式
b.不严格定义:同一个对象,具有不同的形态

1.2 多态的前提
a.必须有继承关系,或者实现关系
b.必须有方法的重写
c.有父类引用指向子类对象
只有满足以上三个前提,才有多态

1.3 多态的体现
语言表达:父类类型的变量 指向了子类类型的变量(地址)
代码表达:

1
Parent P = new Sub();
范例:
1
Animal A = new Dog();(假设Dog已经继承了Animal,并重写了某个方法)
1.4 多态调用方法的特点
a.多态调用方法时,编译阶段看父类
b.多态调用方法时,运行阶段看子类
总结:多态调用方法的特点是编译看父,运行看子

多态成员访问特点:
•成员变量:编译看父,执行看父
•成员方法:编译看父,执行看子

为什么成员变量和成员方法访问不一样
•因为成员方法有重写,成员变量没有

1.5 多态的好处

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestDemo02 {
public static void main(String[] args) {
Dog dogname = new Dog();
Feed_Animal(dogname);
Cat catname = new Cat();
Feed_Animal(catname);
}

public static void Feed_Animal(Animal an){
System.out.println("Come to Eat");
an.eat();

}
}

总结:多态提供了代码的扩展性/灵活性
具体体现:定义方法时,使用父类类型作为参数,将来在使用时,使用具体的子类型参与操作

1.6 多态的弊端
多态调用特点:编译看父,运行看子
弊端:使用多态时,只能调用子父类都有的方法,不能调用子类独有的方法

1.7 多态弊端的解决方法-向下转型

1
2
3
4
5
6
7
8
//向上转型(把子类类型转换成父类类型):
Animal an = new Dog();
dd.eat();
Dog dd = new Animal();

//向下转型(把父类类型转回子类类型):
Dog dog = (Dog) dd;
dog.sleep(;)

1.8 转型可能出现的异常
ClassCastException 类型转换异常
当多态一个子类是A,向下转型是另一个子类B时,会出现转换异常。

1.9 instanceof 关键字介绍
可以判断一个对象,是否是我们指定类的对象

boolean b = 对象名 instanceof

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
Animal an = new Cat();
an.eat();

if(an instanceof Dog){
Dog dd = (Dog)an;
dd.Housekeeping();
}
if(an instanceof Cat){
Cat cc = (Cat)an;
cc.catchMouse();
}

二. 内部类
2.1 什么是内部类
所谓的内部类就是在一个类A内部定义一个另外一个类B,此时类B内部类,类A外部类

按照内部类在类中定义的位置不同,可以分为如下两种形式
•在类的成员位置:成员内部类
•在类的局部位置:局部内部类

创建格式:
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
范例:Outer.Inner oi = new Outer().new Inner();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Human {
int age;
String name;
// 内部类
// 成员内部类
class Heart{
int JumpCount;
public void Jump(){
System.out.println("Heart Jump");
}
}
// 局部内部类
public void Show(){
class xxx{ }
}
}

成员内部类有两个特点:
a.在成员内部类中可以无条件访问外部类的任何成员(包括私有)
b.外部类要访问内部类的成员,必须创建对象

在测试类中创建成员内部类对象写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static void main(String[] args) {
//创建外部类对象
Human H1 = new Human();
//Java 规定想要创建内部类的对象,必须先创建外部类的对象,然后通过外部类对象才能创建内部类对象
Human.Heart HH1 = new Human().new Heart();
//也可以这么写
Human.Heart HH2 = H1.new Heart();
}

public class Outer{
private int num = 10;
private class Inner{
public void show(){
System.out.println(num)
}
}
public void method(){
Inner i = new Inner();
i.show();
}
}

public class OuterDemo{
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}

局部内部类:
局部内部类是在方法中定义的类,所有外交无法直接使用,需要在方法内部创建对象并使用
该类可以直接访问外部类的成员,也可以访问方法内的局部变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Outer{
private int num = 10;}
public void method(){
int num2 = 20;
class Inner{
public void show(){
System.out.println(num)
System.out.println(num2)
}
}
Inner i = new Inner();
i.show();
}

public class OuterDemo{
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}

2.3 内部类编译之后的字节码文件
内部类编译之后的字节码文件名:
外部类名$内部类名
范例:
Human$Heart.class

2.4 匿名内部类
•什么是匿名内部类
概念:局部内部类的简化形式,简化到不需要内部类的名字

•前提:存在一个类或接口,这里的类可以是具体类也可以是抽象类

•匿名内部类的作用
匿名内部类可以帮助我们快速的创建一个父类的子类对象或者一个接口的实现类对象

•本质:是一个继承了该类或者实现类该类接口的子类匿名对象

•格式:
new 类名或接口名(){
重写方法;
};

范例:

1
2
3
new Inter(){
public void show(){}
}

•匿名内部类的使用特点1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

public class TestDemo06 {
public static void main(String[] args) {
//使用匿名内部类
Animal dd = new Animal(){
@Override
public void eat() {
System.out.println("Dog eat");
}

@Override
public void sleep() {
System.out.println("Cat eat");
}
};

dd.eat();
dd.sleep();

Animal pp = new Animal() {
@Override
public void eat() {
System.out.println("Pig eat");
}

@Override
public void sleep() {
System.out.println("Pig sleep");
}
};
pp.eat();
pp.sleep();
}
}

•匿名内部类的使用特点2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//定义接口
public interface Flyable {
public abstract void fly();
}


//创建实现类
public class Bird implements Flyable{
@Override
public void fly() {
System.out.println("Bird Fly");
}
}

public class TestDemo {
public static void main(String[] args) {
Bird bd = new Bird();
bd.fly();
//Anonymous

// new Flyable(){
// @Override
// public void fly() {
// System.out.println("bird fly");
// }
// };
Flyable fae = new Flyable(){
@Override
public void fly() {
System.out.println("bird fly");
}
};
fae.fly();
//调用方法
/*
method(new Bird());
method(new Flyable() {
@Override
public void fly() {
System.out.println("Fly Fly");
}
});*/
}

public static void method(Flyable ff) {
ff.fly();
}
}

总结匿名内部类的格式:

1
2
3
父类名/接口名 对象名 = new 父类名/接口名(){
//重写父类或接口中所有的抽象方法
};

三. 权限修饰符
Java中一共有4中常见的权限修饰符

1

1
2
3
4
5
6
public class Student {
public int size;
protected int grade;
int age;
private int height;
}

public protected (空的) private
同一类中 √ √ √ √
同一类中(子类与无关类) √ √ √ X
不同包的子类 √ √ X X
不同包中的无关类 √ X X X
一般来说:
···成员方法和构造方法是public修饰符的
···成员变量是private修饰的
在极个别的情况下,构造方法也可能是private(单例设计模式)

四.代码块
什么叫做代码块:由一对大括号扩起来的一句或多句代码,就是一个代码块

4.1 构造代码块
格式:

1
2
3
4
5
6
public class 类名{
//代码
{

}
}

构造代码块什么时候执行
每次调用构造方法创建对象之前执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Dog {
int age;
String name;
public void bark(){
System.out.println("Doge");
}
//构造方法
public Dog(){
System.out.println("Mtehod");
}

//构造代码块
{
System.out.println("This is Code Block");
}
}


public class TestDemo09 {
public static void main(String[] args) {
//Create Dog Object
Dog dd = new Dog();
dd.bark();
}
}

//输出
This is Code Block
Mtehod
Doge
4.2 静态代码块
格式:

1
2
3
4
5
public class 类名{
static{
//静态代码块
}
}

随着类到加载而执行,且只执行一次,优先于构造方法执行

Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Pig {
int age;
String name;
public void sleep(){
System.out.println("Pig sleep");
}
public Pig(){
System.out.println("Pig Pig");
}
static {
System.out.println("This is Static Code Block");
}
}

public class TestDemo10 {
public static void main(String[] args) {
Pig pgg = new Pig();
pgg.sleep();
//只要使用Pig类,就会加载到内存,即时立即执行静态代码块
Pig pgg2 = new Pig();
}
}

输出:
This is Static Code Block
Pig Pig
Pig sleep
Pig Pig

总结:
多态的前提:
a.必须有extend或impelement
b.必须有方法的重写

多态的格式:
父类类型 对象名 = new 子类类型();
接口类型 对象名 = new 实现类类型();

多态调用方法时的特点:编译看父,运行看子
好处:提高代码的扩展性
弊端:多态只能调用子父类共有的方法,无法调用子类特有的方法

向上转型:把子类类型 赋值给 父类类型

Animal an = new Dog();
向下转型:必须有向上转型,才能向下转型

Dog dd = (Dog)an;
关键字:instanceof

if(an instanceof Dog){
Dog dd = (Dog)an;
}
内部类概念:在一个类的内部定义另一个类

匿名内部类:

父类/接口 = new 父类/接口(){
//重写父类或接口中的所有抽象方法
};
修饰符的作用:
public
protected
空的
private

代码块:
构造代码块:
格式:
类中方法外一个大括号

{

}
每次执行

静态代码块:
类中方法外一个static大括号

static{

}
仅执行一次

一. final关键字
1.1 final在Java中是一个定义修饰符:修饰类,修饰方法,修饰局部变量,修饰成员变量,修饰引用类型变量
1.2 final的作用和介绍
•final修饰类,不能被继承(只能做子类)。
•final修饰方法,不能被@override
•final修饰局部变量:被final修饰的局部变量,表示该变量只能赋值一次。(在循环框中,每次赋值都是新的局部变量)
•final修饰引用类型变量
final修饰引用类型变量,表示该引用类型变量地址值中表示的地址值不能改变。
注意:final修饰引用变量,只能表示引用变量的地址不能改变,并不代表地址所指向的成员值是可以改变的。
•final修饰成员变量,只能赋值一次,必须赋值。
但是赋值可以有两种选择。
a.定义该成员变量时赋值。
b.或者在构造方法中给该成员变量赋值。

总之,final修饰的成员变量,必须在创建对象之前有值。

final和abstract冲突。

二. static :静态关键字
2.1 概述:也是一个修饰符,用于修饰类中的成员变量/方法,被static修饰的成员称为静态成员/类成员。

被static修饰的成员,不属于任何一个对象,属于整个类,被所有对象共享(这也是判断是否使用静态关键字的条件)

2.2 定义和格式
•类变量:就是使用static修饰的成员变量,称之为类变量/静态变量
特点:静态变量/类变量,在内存方法中的静态区,只有一份,所有对象共享它
•静态方法:就是使用static修饰的方法,也称为类方法。
特点:正常的方法必须通过对象才能调用,静态方法不需要通过对象,通过类名就可以直接调用

2.3 静态和非静态之间的相互调用
静态成员变量
静态成员方法
与类是同级,只要类加载到内存,静态的成员变量/成员方法就存在(对象不一定存在)

非静态成员变量
非静态成员方法
必须创建对象之后才能访问/调用

生命周期:
静态出现的要比非静态要早

非静态成员方法:
•能访问静态的成员变量
•能访问非静态的成员变量
•能访问静态的成员方法
•能访问非静态的成员方法

静态成员方法:
•能访问静态的成员变量
•能访问静态的成员方法

结论:
a.静态与静态之间,非静态与非静态之间,能相互访问
b.静态可以访问静态,但是静态不能访问非静态
即:静态成员方法只能访问静态成员

2.4 建议调用格式
静态的成员变量
对象名.静态成员变量 [可以访问,但是不建议]
类名.静态成员变量 [建议访问的方式]

静态的成员方法
对象名。静态成员方法 [可以访问,不建议]
类名.静态成员方法 [建议的访问方式]
总结:静态成员虽然可以通过对象名去访问/嗲用,但是更建议通过类名去访问/调用

三. 接口
3.1 概述
也是一种引用类型,接口是方法的集合(接口中主要写方法)
接口是一种公共的规范标准,只要符合规范标准,就可以通用
Java中的接口更多是体现着对行为的抽象。

3.2 定义格式
定义类:class
定义接口:interface
定义枚举:enum
定义注解:@interface

1
2
3
4
5
public interface interfaceName{
abstract method [JDK 7]
default method & static method [JDK 8]
private method & private static method [JDK 9]
}

接口的特点:
•接口用关键字interface修饰
public interface接口名{}
•类实现接口用implements表示
public class 类名 implements 接口名{}
•接口不能实例化
参照多态的方式,通过实现类对象实例化,叫做接口多态。
多态的形式:具体类多态,抽象类多态,接口多态
多态的前提:有继承或实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象
•接口的实现类
要么重写接口中所有的抽象方法
要么是抽象类

3.3 接口的使用
a.和abstract method类似,接口也是不能创建对象(new object)的
b.接口也是作为Super interface使用的,用于被其他类 实现 的
c.继承使用extends关键字,实现使用”implements”关键字

使用方式:

1
2
3
4
5
public class 实现类 implements interfaceName{
//实现类必须重写接口中的所有抽象方法
//实现类可以选择性重写默认方法但是@override后不能加default
//静态方法通过类名/接口名直接调用的,没有@override说法
}

3.4 接口的多实现
格式:

1
2
3
4
5
6
public class 实现类 implements interface1,interface2...{
//实现类需要重写所有接口中的所有抽象方法
//如果有抽象方法是一样的,那么实现类只需要重写一次
//如果接口中有一样的默认方法,那么实现类必须重写一次!
//静态方法没有重写的概念,就算多个接口中有一样的静态方法也不冲突,通过各自所在的接口名调用,没有歧义
}

3.5 实现和继承的优先级问题
一个类 可以在继承一个父类的同时实现多个接口(继承和实现可以同时存在)
格式:

1
2
3
public class 子类/实现类 exttends 父类 implements 接口,接口1{

}

继承的优先级 高于 实现,所以必须先extends 后 implements

3.6 接口的多继承
类和类直接:继承关系,只能单继承,但是可以多层继承
类和接口:实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
接口和接口:继承关系,可以单继承,也可以多继承
格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface MyInter extends Inter1,Inter2{
MyInter 接口包含了Inter1和Inter2接口所有东西
}

例:
public class MyClass impelements MyInter{

}

public class MyClass impelements Inter1,Inter{

}
等价

3.7 接口中其他成员特点
•接口中,无法定义成员变量,但是可以定义常量(字面值常量,由public static final修饰的常量),其值不可改变,默认使用public static final修饰
【public static final】数据类型 常量名 = 值;【常量名一般纯大写,多个单词用”_”分隔】

•接口中,没有构造方法,也不能创建对象,因为接口主要是对行为进行抽象的,是没有具体存在
一个类如果没有父类,默认继承自Object类

•接口中,没有静态代码块
•【public static final】可省略直接 数据类型 常量名 = 值。但是默认是存在的

•成员方法
只能是抽象方法
默认修饰符public abstract

抽象类和接口的区别:
•成员区别

抽象类 变量,常量;有构造方法;有抽象方法,也有非抽象方法
接口 常量;抽象方法
•关系区别

类与类 继承,单继承
类与接口 实现,可以单实现,也可以多实现
接口与接口 继承,但继承,多继承
•设计理念区别

抽象类 对类抽象,包括属性,行为
接口 对行为抽象,主要是行为
3.8 接口名作为形参和返回值
•方法的形参是接口名,其实需要的是该接哦哭的实现类对象
•方法的返回值是接口名,其实返回的是该接口的实现类对象

总结:
描述final
修饰类:该类不能被继承
修饰方法:该方法不能被重写
修饰变量:该变量只能赋值一次
——局部变量:可以在定义时赋值,也可以先定义后赋值
——成员变量:可以在定义时赋值,也可以在构造方法中赋值
——引用类型变量:表示该引用类型变量的地址不能改变,但是地址内成员的值是可以改变的

static关键字修饰的变量调用方式
类名.成员变量名 【建议的使用方式】

static关键字修饰的方法调用方式
类名.成员() 【建议的使用方式】

接口定义格式:

1
2
3
4
5
public interface interfaceName{
//抽象方法[最多使用]
//默认方法
//静态方法
}

接口实现方式:

1
2
3
4
5
public class 实现类 impelements interfaceName01,02{
//a.重写所有抽象方法,如果有相同,仅需重写一次
//b.选择性重写默认方法,如果相同必须重写一次
//c.静态方法没有重写的概念
}

接口中其他成员特点:
a.没有成员变量,只有常量 【public static final】数据类型 常量名 = 值;
b.没有构造方法,也不能创建对象
c.没有静态代码块

一.
匿名对象:没有名字的对象
指new对象,但是不用对象名来接收,但不是没有name属性。
使用场景:
当一个对象我们只需要使用一次时,就可以选择使用匿名对象。

二.继承

2.1
概念:在一个已知类A的基础上,创建新类B的过程,称之为继承
继承是面向对象三大特征之一。可以使得子类具有父类对属性和方法,还可以在子类中重新定义,追加属性和方法

这里类A称为SuperClass(父/基/超)类
这里类B称为SubClass(子/派生)类

格式:

1
2
3
4
5
6
7
8
9
public class SuperClass{
//member varriable
//member method
}

public class SubClass extends SuperClass{
//Automatically inherit the SupeClass's varriavle & method
//Also can add self varriable & method
}

优势:
a.提高代码复用性(多个类相同对成员可以放到同一个类中)
b.类和类有了关系,提高了代码的维护性,为多态提供前提(如果方法的代码需要修改,修改溢出即可)

弊端:
a.继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时,子类也不得不跟着变化,削弱了子类的独立性

2.2 子类不能继承的内容
a.父类SuperClass的构造方法子类无法继承!!(因为构造方法和类名是一样的)
b.父类SuperClass的私有成员private menmber,子类可以继承,但是不能直接使用。可以使用get和set方法间接使用。

继承后的特点——成员变量
a.当子父类的成员变量名不同时,访问成员变量是没有歧义的,写哪个变量就是哪个变量。
b.当子父类变量同名时,在子类中会根据就近原则,优先访问子类自己的那个成员变量。
c.在子类方法中,使用super.methodName,就会访问SuperClass的成员变量。
就近原则,层层递进:
•子类局部范围找
•子类成员范围找
•父类成员范围找
•如果都没有则报错

super关键字都用法和this关键字用法相似
•this:代表本类成员对象的引用(this关键字指向调用该方法对象,一般是在当前类使用this关键字,使用this常代表本类对象引用)
•super:代表父类存储空间的标识(可以理解为父类对象引用)

继承后的特点——成员方法【重点】
a.当子父类的成员方法名不同时,访问成员方法名是没有歧义的,写哪个方法名就是哪个方法名。
b.当子父类的成员方法同名时,使用子类对象调用该方法,会根据就近原则,优先访问子类自己的那个成员方法。
c.无法通过子类对象使用super调用父类方法。但是可以在子类方法中使用super.methodName()调用父类的同名方法

2.3 重写的概念和应用

重写的概念:
方法的重载(overload):
在同一个类中,出现了方法名应用,但是参数列表(参数个数|类型|顺序)不一样的各种方法,称为方法的重载
方法的重写(override):
在继承关系sub-super中,子类中出现了一个和父类除了方法体,其他一模一样的方法,称为方法的重写

重写的应用:
子类继承父类时,会继承父类的方法,那么当子类发现继承过来的方法功能不足或不适用时,子类就可以重写该方法,重新实现自己需要的方法即可。

2.4 @override注解
@xxx这种称之为注解,英文名annotation
@override 此注解方法称之为方法重写注解,主要作用就是检查重写的方法是否格式正确(符合父类的除了方法体一模一样)

2.5 方法重写的注意事项
a.方法重写是发生在子父类sub-super之间的关系
b.子类方法重写父类方法时,必须要保证权限大于等于父类的权限(一般来说,父类方法权限=子类方法权限)
Java中四大权限(从大到小依次为:public-protected-default-private)
c.方法重写时,除了方法体,其他都要和父类一模一样。(虽然权限可以不一样,但是一般也写一样的权限)
d.私有方法不能被重写(父类私有成员子类是不能继承的)

2.6 继承后的特点——构造方法
子类中所有的构造方法默认都会访问父类中无参的构造方法,子类初始化之前,一定要先完成父类数据的初始化
构造方法特点介绍:
a.子类无法继承父类的构造方法
b.在子类的任何构造方法的第一行,都有默认一句代码super(),代表调用父类的无参构造。

构造方法总结:
a.子类的任何构造,第一行都会调用父类的无参构造。
如果父类没有无参构造:
•通过super关键字前显示的调用父类的带参构造方法
•在父类中提供一个无参构造方法
b.子类的构造方法第一行,super是默认存在的,可以省略不写,但是默认有的

小结:
a.子类的构造方法中默认有一句super()调用父类的无参构造,我们可以手动改写super(…)调用父类的有参构造,具体哪个构造,由参数决定
b.super(…)和this(…)必须在第一行,所有不能重复重写
c.super(…)和this(…)调用父的构造和子类自己的其他构造,具体哪个构造由参数决定
d.super(…)调用父类的有参构造,初始化父类继承的成员变量。
e.this(…)调用子类的其他构造方法

关键字 访问成员变量 访问构造方法 访问成员方法
this this.成员变量,访问本类成员变量 this(…)访问本类构造方法 this.成员方法(…) 访问本类成员方法
super super.成员变量,访问父类成员变量 super(…)访问父类构造方法 super.成员方法(…) 访问父类成员方法
2.7 Java中继承的特点
a.Java只支持单继承,不支持多继承。(一个类最多只有一个super)
b.一个类可以有多个子类(一个super可以有多个sub)
c.可以多层继承(sub有自己的super,相对还有super的super)
总结:Java只支持单继承,但是可以多层继承。

三. 抽象类
3.1 抽象类的概念和引入

抽象类的概念:
a.抽象方法:只有方法的声明,没有方法的实现(即没有方法体)
b.含有抽象方法的类,就是一个抽象类

使用格式
•抽象方法
public abstract 返回值类 方法名(参数列表);
•抽象类
public abstract class 类名{
抽象方法
正常方法
}
注意:抽象类不能创建对象,总是作为父类。
抽象类不能创建对象,需要有子类继承它,并且重写所有抽象类后,该子类才能创建对象。

3.2抽象类的特征:
抽象类具备了含有抽象方法的能力,同时失去了创建对象的能力。
注意事项:
a.抽象类不能创建对象
b.抽象类有构造方法,用于初始化类中的成员变量
c.抽象类中不一定含有抽象方法,有抽象方法的类一定是抽象类(一般来说,抽象类中是有抽象方法的)
d.抽象类的子类必须重写抽象类的所有抽象方法,否则子类还是一个抽象类
e.抽象类存在的意义就是被子类继承的,为子类提供模版

3.3 抽象类的成员特点
•成员变量:可以是变量,也可以是常量
•构造方法:有构造方法,本身不能实例化,用于子类访问父类数据的初始化
•成员方法:
a.可以有抽象方法:限定子类必须完成某些动作
b.也可以有非抽象方法:提高代码复用性

3.4 抽象类名作为形参和返回值
•方法的形参是抽象类名,其实需要的是该抽象类的子类对象
•方法的返回值是抽象类名,其实返回的是该抽象类的子类对象

3.5 模版设计模式

总结:
继承:
a.继承的格式
public class 子类 extends 父亲{}
b.不能继承的内容
I.构造方法不能继承
II.私有成员子类可以继承但是不能直接使用(间接使用,通过get/set方法使用)
c.继承后成员变量和成员方法的特点:
I.不同名,没有歧义
II.同名时在子类中优先调用子类自己的成员
III.可以使用关键字
super.变量名 访问父类的同名成员变量
super.方法名() 访问父类的同名成员方法
d.方法的重写
方法的重写:在继承关系中,子类有一个和父类除了方法体其他一模一样的方法,该方法称为重写
什么时候需要重写:
当子类继承父类的方法后,发现父类方法不实用,子类就可以重写该方法
重写时可以用override帮助检查格式是否正确
e.super(…)
用于子类的构造方法第一行,调用父类的构造方法,具体是哪一个构造
由super(参数)中的参数决定
f.this(…)
用于本类的构造方法第一行,调用本类的构造方法,具体是哪一个构造
由this(参数)中的参数决定
g.Java的继承特点:
只支持单继承,但是支持多层继承
抽象类:
a.抽象方法格式:
public abstract void method();
抽象类格式:
public abstract class className{可能有抽象方法,可以没有抽象方法}
b.抽象类的使用方式:
使用子类继承抽象类,重写所有抽象方法后,子类才能创建对象。
c.抽象类的意义:
给子类继承的,为子类提供的模版(模版设计模式)

一.数据输入
1.1 Scanner使用基本步骤
①导包
import java.util.Scanner;
导包的动作必须出现在定义上面。
②创建对象
Scanner sc = new Scanner(System.in);
上面这个格式里,只有变量名sc可以变,其他都不允许变。
③接收数据
int i = sc.nextInt();
上面这个格式里,只有变量名i可以变,其他都不允许变。

一.API
1.1 API (Application Programming Interface) 概述:应用程序编程接口

Java API:指的就是JDK中提供的各种功能的Java类
这些类将底层的实现封装了起来,可以通过帮助文档来学习这些API如何使用

1.2 如何使用帮助文档:
①打开使用版本的JDK文档
②索引框输入要查询的类
③查看类在哪个包下
④看类的描述
⑤看构造方法
⑥看成员方法

注意:调用方法时,如果方法有明确的返回值,可以用变量接收

二. String
2.1 String 概述:
String类在java.lang 包下,使用时不需要导入包。

String类代表字符串,Java程序中所有的字符串文字(例如”abc”)都被实现为此类的实例
也就是说,Java程序中所有的双引号字符串,都是String类的对象

字符串的特点:

字符串不可变,它们的值在创建后不能被更改
虽然String值不可变,但是它们可以被共享
字符串效果上相当于字符数组(char[] ,JDK8及之前是字符数组,JDK9之后是字节数组),但是底层原理是字节数组(byte[] )
2.2 String的常用构造方法:

方法名 说明
public String() 创建一个空白字符串对象,不含任何内容
public String(char[] chs) 根据字符组的内容,来创建字符串对象
public String(byte[] bys) 根据字节组的内容,来创建字符串对象
String s = “abc” 直接赋值的方式创建字符串对象,内容就是abc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AIO_ServerSocketChannel {
public static void main(String[] args){
String s1 = new String();
System.out.println(s1);//无内容,因为未赋值

char[] chs = {'a','b','c'};
String s2 = new String(chs);
System.out.println(s2);//abc

byte[] bys = {97,98,99};
String s3 = new String(bys);
System.out.println(s3);//abc,因为使用的是ASCII码

String s4 = "abc"
System.out.println(s4);//abc
}
}

推荐直接使用赋值方式得到字符串对象

2.3 String对象的特点
1)通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同

char[] chs ={‘a’,’b’,’c’};
String s1 = new String(chs);
String s2 = new String(chs);
在上述代码中,JVM会熟悉创建一个字符数组,然后每次new的时候都会有一个新的地址,只不过s1和s2参考的字符串内容都是相同的

2)以 “” 方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String对象,并在字符串池中维护

String s3 = “abc”;
String s4 = “abc”;
在上述代码中,针对第一行代码,JVM会建立一个String对象放在字符串池中,并给s3参考;
第二行让s4直接参考字符串池中的String对象,也就是说它们本质上还是同一个对象

内存过程:

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args){
char[] chs ={'a','b','c'};
String s1 = new String(chs);
String s2 = new String(chs);
System.out.println(s1 == s2);//false

String s3 = "abc";
String s4 = "abc";
System.out.println(s3 == s4);//true
System.out.println(s1 == s3);//false
}

栈内存:
方法main
char[] chs 假设地址001
String s1 假设地址002
String s2 假设地址003
String s3 假设地址004
String s4 假设地址004

堆内存:
new char[3]
001
0 ‘a’
1 ‘b’
2 ‘c’

new String()
002
ref 001

new String()
003
ref 001

常量池
004 abc 赋值给s3与s4

2.4 字符串的比较
使用 == 做比较

基本类型:比较的是数据值是否相同
引用类型:比较的是地址值是否相同
字符串是对象,它比较内容是否相同,是通过一个方法来实现的,这个方法叫:equals()

public boolean equals(Object anObject);将此字符串与指定对象进行比较。由于比较的是字符串对象,所以参数直接传递一个字符串
遍历字符串,首先要能够获取到字符串中的每一个字符

public char charAt(int index);返回指定索引处的char值,字符串的索引也是从0开始的
遍历字符串,获取字符串的长度
public int length();返回此字符串的长度
数组的长度:数组名.length
字符串的长度:字符串对象.length()
遍历字符串通用格式:
1
2
3
for(int i=0;i<s.length();i++ ){
s.charAt(i);//就是指定索引处的字符值
}
•大写字母:ch>=’A’ && ch <= ‘Z’
•小写字母:ch>=’a’ && ch <= ‘z’
•数字:ch>=’0’ && ch <= ‘9’

2.5 通过帮助文档查看String中的方法

方法名 说明
public boolean equals(Object anObject) 比较字符串的内容,严格区分大小写(用户名&密码)
public char charAt(int Index) 返回索引处的char值
public int length() 返回此字符串的长度
三. StringBuilder
3.1 概述
StringBuilder是一个可变的字符串类,可以把它当作一个容器。
这里的可变指的是StringBuilder对象中的内容是可变的

String和StringBuilder的区别:

String:内容是不可变的
StringBuilder:内容是可变的
如果对字符串String进行拼接操作,每次拼接都会构建一个新的String对象,耗费时间与内存空间。
因此使用StringBuilder可类可以解决这个问题。

3.2 StringBuilder的构造方法

方法名 说明
public StringBuilder() 创建一个空白可变字符串对象,不含任何内容
public StringBuilder(String str) 根据字符串内容,创建可变字符串对象
public StringBuilder(int Capacity) 构造一个没有字符的字符串构建器,以及由capcacity参数指定的初始容量
public StringBuilder(CharSequence seq) 构造一个字符串构建器,其中包含与指定的CharSequence相同的字符
3.3 StringBuilder的添加和反转方法

方法名 说明
public StringBuilder append(任意类型) 添加数据,并返回数据本身
public StringBuilder reserve() 返回相反的字符序列

1
2
3
4
5
6
7
8
9
10
11
public class SBDemo01{
public static void main(String[] args){
StringBuilder sb = new StringBuilder();

sb.append("a").append("b");//链式编程
System.out.println(sb);//ab

sb.reserve();
System.out.println(sb);//ba
}
}

3.4 StringBuilder 和 String 相互转换
a.从StringBuilder转换为String
public String toString();通过toString()就可以实现把StringBuilder转换为String

b.从String转换为StringBuilder
public StringBuilder(String s);通过构造方法就可以把String转换为StringBuilder

1
2
3
4
5
6
7
8
9
10
11
public class SBDemo01{
public static void main(String[] args){
StringBuilder sb = new StringBuilder();

sb.append("abc");
String s = sb.toString(s);

String t = "hello";
StringBuilder new_sb = new StringBuilder(s);
}
}

3.5 通过帮助文档查看 StringBuilder 中的方法

方法名 说明
public StringBuilder append(任意类型) 添加数据,并返回数据本身
public StringBuilder reserve() 返回相反的字符序列
public String toString() 通过toString()就可以实现把StringBuilder转换为String

一. Debug概述
Debug是程序员使用的程序调试工具,他可以用于查看程序的执行流程,也可以用来追踪程序执行过程来调试程序。
Debug操作流程:
Debug调试,又被称为断点调试,断点其实是一个标记,告诉我们从哪里开始查看。
执行流程:
①如何加断点
选择设置断点的代码行,在行号左边的区域单击鼠标左键即可
②如果运行加了断点的程序
在代码区域右键Debug执行
③看哪里
看debug和console窗口
④点哪里
点step info(F7)这个箭头,也可以直接按F7,执行完点stop结束
⑤如何删除断点
选择要删除的断点,单击鼠标左键即可

Debug的使用:
•查看循环求偶数和的执行流程。
•查看方法调用的执行流程

注意:如果数据来自于键盘,一定要记住输入数据,不然造成阻塞

二.类和对象
2.1 什么是对象:万物皆对象
2.2 什么是面向对象:关注具体的事物信息
2.3 什么是类:类是对现实生活中一类具有共同属性和行为的事物的抽象

类的特点:
•类是对象的数据类型
•类是具有相同属性和行为的一组对象集合

2.4 什么是对象的属性
属性:对象的各种特征,每个对象的每个属性都有特定的值
2.5 什么是对象的行为
行为:对象能够执行的操作
2.6 类和对象的关系
类:类是对现实生活中一类具有共同属性和行为的事物抽象
对象:是能够看得到摸得到的真实存在的实体

类是对象的抽象
对象是类的实体

2.7 类的定义
类的重要性:是Java程序的重要组成单位
类是什么:类是对现实生活中一类具有共同属性和行为的事物抽象,确定对象将会拥有的属性和行为

类的组成:属性 和 行为
•属性:在类中通过成员变量来体现(类中方法外的变量)
•行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)

类的定义步骤:
①定义类
②编写类的成员变量
③编写类的成员方法

1
2
3
4
5
6
7
8
9

public class 类名{
//成员变量
变量1的数据类型 变量1
变量2的数据类型 变量2
//成员方法
方法1
方法2
}

2.8 对象的使用
创建对象:
•格式: 类名 对象名 = new 类名();
•范例: Phone p = new Phone();

使用对象:
a.使用成员变量
•格式:对象名.变量名
•范例:p.brand

b.使用成员方法
•格式:对象名.方法名()
•范例:p.call()

三.对象内存图
3.1 对象内存图(单个对象)
例子

1
2
3
4
5
6
7
8
9
10
11
12
13
public class StudentTest01{
public static void main(String[] args){
Student s = new Student();
System.out.println(s);
System.out.println(s.name+","+s.age);
s.name = "a";
s.age = 1;
System.out.println(s.name+","+s.age);

s.study();
s.doHomework();
}
}

栈内存:
main
Student s 地址值(假设为)001
s.study();
方法:study,
调用者s(001),执行完毕后就销毁
s.doHomework();
方法:doHomework,
调用者s(001),执行完毕后就销毁

堆内存:
new Student 001
name “a”
age 1

3.2 对象内存图(多个对象)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class StudentTest01{
public static void main(String[] args){
Student s1 = new Student();
System.out.println(s1);

System.out.println(s1.name+","+s1.age);
s1.name = "a";
s1.age = 1;
System.out.println(s1.name+","+s1.age);

s1.study();
s1.doHomework();

Student s2 = new Student();
System.out.println(s2);

System.out.println(s2.name+","+s2.age);
s2.name = "b";
s2.age = 2;
System.out.println(s2.name+","+s2.age);

s2.study();
s2.doHomework();
}
}

栈内存:
main
Student s1 地址值(假设为)001
s1.study();
方法:study,
调用者s(001),执行完毕后就销毁
s1.doHomework();
方法:doHomework,
调用者s(001),执行完毕后就销毁

Student s2 地址值(假设为)002
s2.study();
方法:study,
调用者s(001),执行完毕后就销毁
s2.doHomework();
方法:doHomework,
调用者s(001),执行完毕后就销毁

============================
堆内存:
new Student 001
name “a”
age 1

new Student 002
name “b”
age 2

3.2 对象内存图(多个对象指向相同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class StudentTest01{
public static void main(String[] args){
Student s1 = new Student();

s1.name = "a";
s1.age = 1;
System.out.println(s1.name+","+s1.age);

//将s1赋值给s2
Student s2 = s1;
System.out.println(s2);

s2.name = "b";
s2.age = 2;
System.out.println(s1.name+","+s1.age);
System.out.println(s2.name+","+s2.age);
}
}

栈内存:
main
Student s1 地址值(假设为)001

Student s2 地址值(假设为)001

============================
堆内存:
new Student 001
name “a”
age 1

//s2
new Student 001
name “b”
age 2

输出:
a,1
b,2
b,2

结论:当两个对象指向相同(地址值相同时),其中一个对象修改了堆内存的内容,另一个对象访问时,内容也是改变过的

四.成员变量和局部变量
4.1 什么是成员变量和局部变量
成员变量:类中方法外的称为成员变量
局部变量:在方法中的变量

4.2 成员变量和局部变量的区别

区别 成员变量 局部变量
类中位置不同 类中方法外 方法内或方法声明上
内存中位置不同 堆内存 栈内存
声明周期不同 随着对象的存在而存在,随着对象的消失而消失 随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同 有默认的初始化值 没有默认的初始化值,必须先定义,才能使用
五.封装
5.1 private关键字
•是一个权限修饰符
•可以修饰成员(成员变量和成员方法)
•作用是保护成员不被别的类使用,被 private 修饰的成员只有在本类中才能访问

针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
•提供”get变量名()”方法,用于获取成员变量的值,方法用public修饰
•提供”set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰

5.2 private关键字的使用
一个标准类的编写:
•把成员变量用private修饰
•提供对应的getXxx()/setXxx()方法

5.3 this关键字

①this修饰的变量用于指代成员变量

方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
放到的形参没有与成员变量同名,不带this修饰的变量指的是成员变量
②什么时候使用this

解决局部变量隐藏成员变量
③this:代表所在类的对象引用

记住:方法被哪个对象引用,this就代表哪个对象
5.4 this内存原理

1
2
3
4
5
6
7
public class StudentDemo(){
Student s1 = new Student();
s1.setName("a");

Student s2 = new Student();
s2.setName("b");
}

栈内存:
方法main
Student s1 假设内存地址001

方法:setName
参数:name:”a”
调用者:s1(001)
this: s1(001)
使用完毕销毁

Student s2 假设内存地址002
参数:name:”b”
调用者:s1(002)
this: s1(002)
使用完毕销毁

堆内存:
new Student 001
name a
age 1

new Student 002
name b
age 2

5.5 封装
a.封装概述
是面向对象的三大特征之一(封装,继承,多态)
是面向对象编程语言对客观实际的模拟,客观世界里成员变量都是隐藏在对象内部的,外部是无法操作的

b.封装原则
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
成员变量private,提供对应的getXxx()/setXxx()方法

c.封装的好处
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性

六.构造方法
6.1 构造方法概述
构造方法是一种特殊的方法
作用:创建对象
格式:
public class 类名{
修饰符 类名(参数){

}
}
功能:主要是完成对象数据的初始化

6.2 构造方法的注意事项
①构造方法的创建

如果没有定义构造方法,系统将给出一个 默认的 无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法
②构造方法的重载

如果自定义来带参构造方法,还要使用无参构造方法,将必须再写一个无参数构造方法
③推荐的使用方式

无论是否使用,都手工书写无参数构造方法
6.3 标准类的制作
①成员变量

使用private修饰
②构造方法
提供一个无参构造方法
提供一个带多个参数的构造方法
③成员方法
提供每一个成员变量对应的setXxx()/getXxx()
提供一个显示对象信息的show()
④创建对象并为其成员变量赋值的两种方式
无参构造方法创建后使用setXxx()赋值
使用带参构造方法直接创建带有属性值的对象

一.方法概述
1.1
方法(method)就是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集。
注意:
•方法必须先创建才可以使用,该过程称为方法定义
•方法创建后并不是直接运行的,需要手动使用后才执行,该过程称为方法调用
1.2 方法的定义和调用
方法定义
格式:

1
2
3
4
5
6
7
public static void 方法名(){
//方法体
}
范例:
public static void isEvenNumber(){
//方法体
}

方法调用
•格式:方法名()
•范例:isEvenNumber()

注意:方法一定要先定义后调用,不然会报错

1.3 带参数方法的定义和调用
带参数方法的定义:
•格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void 方法名(参数){… …}
•格式(单个参数):

public static void 方法名(数据类型 变量名){… …}
•范例(单个参数):

public static void isEvenNumber(int number){… …}
•格式(多个参数):

public static void 方法名(数据类型 变量名1,数据类型 变量名2){… …}
•范例(多个参数):

public static void isEvenNumber(int number1,int number2){… …}

注意:
•方法定义时,参数中的数据类型和变量名都不能少,缺任一程序报错
•方法定义时,多个参数之间用逗号(,)分隔

带参数方法的调用
•格式:方法名(参数)
•格式(单个参数):方法名(变量名/常量值)
•范例(单个参数):isEvenNumber(5)
•格式(多个参数)方法名(变量名1/常量值1,变量名2/常量值2);
•范例(多个参数):isEvenNumber(5,6)
注意:
方法调用时,参数的数量与类型必须与方法定义中的设置相匹配,否则程序将报错

形参和实参
形参:方法中定义的参数,等同于变量定义格式,例如int number
实参:方法中调用的参数,等同于使用变量或常量,例如10 number

1.4 带返回值方法的定义和调用
带返回值方法的定义
•格式:

1
2
3
4
5
6
7
8
9
public static 数据类型 方法名(参数){
return 数据;
}
•范例:public static boolean isEvenNumber(int number){
return true;
}
•范例:public static int getMax(int a,int b){
return 100;
}

注意:方法定义时,return的返回值与方法定义的数据类型要匹配,不然报错

带返回值方法的调用
•格式1:方法名(参数);
•范例:isEvenNumber(5);
•格式2:数据类型 变量名 = 方法名(参数)
•范例:boolean flag = isEvenNumber(5);
注意:方法的返回值通常会使用变量接收,否则该返回值无意义

1.5 方法的注意事项
•方法不能嵌套定义
•void表示无返回值,可以省略return,也可以单独书写return,后面不加数据。

1.6 方法的通用格式
•格式

1
2
3
4
public static 返回值类型 方法名(参数){
方法体
return 数据;
}

•public static:修饰符
•返回值类型:方法操作完成后,返回的数据类型。如果方法操作完毕,没有数据返回,这里写void,而且方法体中一般不写return。
•方法名:调用方法时使用的标识
•参数:由数据类型和变量名组成,多个参数之间用逗号隔开
•方法体:完成功能的代码块
•return:如果方法操作完毕,有数据返回,用于把数据返回给调用者

•定义方法时,要做到两个明确
明确返回值类型:主要是明确方法操作完毕后是否有数据返回,如果没有,写void,如果有,写对应的数据类型
明确参数:主要是明确参数的类型和数量

•调用方法时
void类型的方法,直接调用即可
非void类型的方法,推荐用变量接收调用

1.6 方法重载
概述:方法重载,是指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载
•多个方法要在同一个类中
•多个方法要具有相同的方法名
•多个方法的参数不同,类型不同,或者数量不同

方法重载的特点:
•重载仅针对方法的定义,与方法的调用无关,调用方式参考标准格式。
•重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,换句话说就是不能通过返回值来判定两个方法是否相互构成重载

1.7 方法的参数传递
基本类型:对应基本数据类型的参数,形式参数的改变,不影响实际参数的值
引用类型:对应引用数据类型的参数,形式参数的改变,影响实际参数的值

一.集合基础
1.1 集合概述
编程时如果要存储多个数据,使用长度固定的数组存储格式,不一定满足需求,耿适应不了变化的需求,此时应选择集合。

集合类的特点:提供一种存储空间可变的 存储模型,存储的数据容量可以发生改变
集合类非常多,首先学习:ArrayList

ArrayList:

可调整大小的数组实现
:是一种特定的数据类型,泛型
使用:
在所有出现的地方可以使用引用数据类型替换
例:ArrayList,ArrayList

1.2 ArrayList构造方法和添加方法

方法名 说明
public ArrayList() 创建一个空的集合对象
public boolean add(E e) 将指定的元素追加到此集合的末尾
public void add(int index,E element) 在此集合中的指定位置插入指定的元素
1.3 ArrayList集合常用方法

方法名 说明
public boolean remove(Object o) 删除指定的元素,返回删除是否成功
public E remove(int index) 删除指定索引处的元素,返回被删的元素
public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
public E get(int index) 返回指定索引处的元素
public int size() 返回集合中的元素的个数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ArrayListDemo {
public static void main(String[] args) {

ArrayList<String> array = new ArrayList<>();

Collections.addAll(array,"a","b","c");

System.out.println(array);

System.out.println(array.remove("b"));

System.out.println(array.remove(1));

System.out.println(array.set(0,"ccc"));

System.out.println(array.get(0));

System.out.println(array.size());
}
}