【Java系列笔记002】Java语言高级(一)

第一章:常用的API

第一节:API概述

1.1 概述

**API:**应用程序编程接口。Java API是一本程序员的字典,是JDK中提供给我们使用的类的说明文档。这些类将底层的代码实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。所以我们可以通过查阅API的方式,来学习Java提供的类,并得知如何使用它们

1.2 API使用步骤

1、打开帮助文档

2、点击显示,找到索引,看到输入框

3、你要找谁,就在输入框里输入,然后回车

4、看包,java.lang下的类不需要导包,其他需要

5、看类的解释和说明

6、学习构造方法

7、使用成员方法

第二节:Scanner类

2.1 什么是Scanner类

**Scanner类的功能:**可以实现键盘输入数据到程序中

引用类型的一般使用步骤:

1、导包

import 包路径.类名称;

在package之后写,但在public之前写

如果需要使用的目标类和当前类位于同一个包下,则可以省略导包语句不写

只有java.lang包下的内容不需要导包,其他的包都需要import语句

2、创建

类名称 对象名=new 类名称();

3、使用

对象名.成员方法名()

package cn....;
import java.util.Scanner;
public class Demo01Scanner{
    public static void main(String[] args){
    	Scanner sc=new Scanner(System.in);//现阶段一成不变
    	//System.in代表从键盘进行输入
        int num=sc.nextInt();//获取键盘输入的一个int数字:
        String str=sc.next();//获取键盘输入的一个字符串;
    }
}

第三节:匿名对象

3.1 匿名对象的说明

创建对象的标准格式:

类名称	对象名=new	类名称();

匿名对象就是只有右边的对象,没有左边的名字和赋值运算符

new 对象名().成员变量;//定义

注意:匿名对象只能使用唯一的依次,下次使用不得不再创建一个新对象

使用建议:如果确定有一个对象只需要使用唯一的一次,就可以用匿名对象

3.2 匿名对象作为返回值的参数
public static void main(String[] args){
    //普通使用Scanner方式:
    Scanner sc=new Scanner(System.in);
    int num=sc.nextInt();
    //匿名对象的方式:
    int num=new Scanner(System.in).nextInt();
    System.out.println("输入的是:"+num);
    //使用一般写法传入参数:
    Scanner sc=new Scanner(System.in);
    methodparam(sc);
    //使用匿名对象来进行传参:
    methodparam(new Scanner(System.in));
}

第四节:ArrayList 集合

4.1 对象数组

数组有一个缺点:一旦创建,程序运行期间长度不可以发生改变

public class Demo01Array{
    public static void main(String[] args){
        //首先创建一个长度为3的数组,里面用来存放Person类型的对象
        Person[] array=new Person[3];
        Person one =new Person("迪丽热巴",18);
        Person two =new Person("古力娜扎",28);
        Person three=new Person("玛尔扎哈",38);
        //将one当中的地址值赋值到数组0号元素位置
        array[0]=one;
        array[1]=two;
        array[2]=three;
        System.out.println(attay[0]);//地址值
        System.out.println(attay[1]);//地址值
        System.out.println(attay[2]);//地址值
        
        System.out.println(attay[1].getName);//古力娜扎
    }
}
4.2 ArrayList 集合概述和基本使用

**与数组的区别:**数组的长度不可以发生改变,但是ArrayList的长度可以发生改变

对于ArrayList来说,有一个代表泛型。

泛型:也就是装在集合当中的所有元素,全部都是统一的什么类型。

注意:1、泛型只能是引用类型,不能是基本类型

2、对于ArrayList集合来说,直接打印得到的不是地址值,而是内容,如果内容是空,得到的是空的中括号,[]

3、创建的时候尖括号泛型说的是什么类型,添加进去的元素就必须是什么类型

package cn.Test2;
import java.util.ArrayList;
public class Arraytest {
    public static void main(String[] args) {
        //创建了一个ArrayList集合,集合的名称是list,里面装的全都是String字符串类型的数据
        //备注:从JDK 1.7+开始,右侧的尖括号内部可以不写内容,但是<>本身还是要写的
        ArrayList<String> list=new ArrayList<>();
        System.out.println(list);
        //向集合中添加一些数据,需要用到add方法
        list.add("赵丽颖");
        System.out.println(list);
        list.add("da");
        list.add("as");
        System.out.println(list);
    }
}

常用方法:(重点)

1、向集合中添加元素,参数的类型和泛型一致,返回值是对应的boolean值 list.add(“想加的元素”);

public boolean add(E e);

2、从集合中获取元素,参数是索引编号,返回值就是对应位置的元素 list.get(索引值);

public E get(int index);

3、从集合中删除元素,参数是索引编号,返回值就是被删除的元素 list.remove(3);

public E remove(int index);

4、获取集合的尺寸长度,返回值是集合中包含的元素个数 list.size();

public int size();
4.3 ArrayList集合存储基本数据

如果希望向集合ArrayList中存储基本类型,必须使用基本类型对应的“包装类”

基本类型包装类(引用类型,包装类都位于java.lang包下)
byteByte
shortShort
intInteger【特殊】
longLong
floatFloat
doubleDouble
charCharacter【特殊】
booleanBoolean

在这八个类名中,除了Integer和Character类以后,其它六个类的类名和基本数据类型一致,只是类名的第一个字母大写即可。

ArrayList<Integer> list=new ArrayList<>();
list.add(100);

从JDK 1.5+开始,支持自动装箱,自动拆箱

**自动装箱:**基本类型----->包装类型

**自动拆箱:**包装类型------>基本类型

第五节: String类

5.1 字符串概括和特点

String类代表字符串,JAVA程序中的所有字符串字面值(如"abc")都作为此类的实例实现

其实就是说:程序中所有双引号字符串,都是String类的对象(就算没有new,也照样是)

字符串的特点:

1、字符串的内容永不可变【重点】

2、正是因为字符串不可改变,所以字符串是可以共享使用的

3、字符串效果上相当于是char[]字符数组,但是底层原理是byte[]字节数组

5.2 字符串的构造方法和创建方法

创建字符串的常见3+1种方式:

三种构造方法:

public String();//创建一个空白字符串,不含有任何内容
String str1=new String();//小括号留空,说明字符串什么内容都没有
public String(char[] array);//根据字符数组的内容,来创建对应的字符串
char[] charArray={'a','b','c'};
String str2=new String(charArray);//abc
public String(byte[] array);//根据字节数组的内容,来创建对应的字符串
byte[] byteArray={97,98,99};
String str3=new String(byteArray);//abc

一种直接创建:

String str="Hello";//右边直接用双引号

注意:直接写上双引号,就是字符串对象

5.3 字符串的常量池

字符串的常量池:程序当中直接写上的双引号字符串,就在字符串常量中,从JDK1.7开始,常量池在堆中

对于基本类型来说,==是进行数值的比较

对于引用类型来说,==是进行【地址值】的比较

常量池的工作内存图:

在这里插入图片描述

注意:

1、对于引用类型来说,==进行的是地址值的比较

2、双引号直接写的字符串在常量池中,new的不在池当中

5.4 字符串的比较相关方法

==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法:

一、严格区分大小写

public boolean equals(Object obj);//参数可以是任何对象,只有参数是一个字符串并且内容相同的才会给true,否则返回flase,任何对象都能用Object进行接收
System.out.println(str1.equals(str2));
System.out.println(str1.equals("Hello"));
System.out.println("Hello".equals(str1));

注意:

1、任何对象都能用Object进行接收

2、equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样

3、如果比较双方一个常量一个变量,推荐把常量字符串写在前面

推荐:“abc”.equals(str); 不推荐:str.equals(“abc”);

 **当str=null时,不推荐的写法会报错:空指针异常(NullPorinterException)**

二、不区分大小写

public boolean equalsIgnoreCase(String str);//忽略大小写,进行内容比较
System.out.println(str1.equalsIgnoreCase(str2));
System.out.println(str1.equalsIgnoreCase("Hello"));
System.out.println("Hello".equalsIgnoreCase(str2));

注意:只有英文字母区分大小写,其他都不区分大小写

5.4 字符串的获取相关方法

String中与获取相关的常用方法:

public int length();//获取字符串中含有的字符个数,拿到字符串长度
int length="asfahfhlafhla".length();
public String concat(String str);//将当前字符串和参数字符串拼接,返回新的字符串
String str3=str1.concat(str2);
public char charAt(int index);//获取指定索引位置的单个字符(索引从0开始)
char ch="Hello".charAt(1);//e
public int indexOf(String str);//查找参数字符串在本字符串中首次出现的索引位置,如果没有,返回-1
int index=str1.indexOf(str2);
5.5 字符串的截取方法

截取方法:

public String substring(int index);//截取从参数位置一直到字符串末尾,返回新字符串
String str2=str1.substring(5);
public String substring(int begin,int end);//截取区间从begin开始,一直到end结束,中间的字符串,而且是个左闭右开,[begin,end)
String str3=str1.substring(4,7);
5.6 字符串的转换相关方法

String中与转换相关的常用方法:

public char[] toCharArray();//将当前字符串拆分成字符数组作为返回值
char[] chars="Hello".toCharArray();
public byte[] getBytes();//获得当前字符串底层的字节数组
byte[] bytes="Hello".getBytes();
public String replace(CharSequence oldString,CharSequence newString);//将所有出现的老字符串替换成为新的字符串,返回替换之后的结果新字符串.CharSequence意思是可以接受字符串类型
String str1="How do you do?";
String str2=str1.replace("o","*");//H*w d* y*u d*?
5.7 字符串的分割相关方法

分割字符串的方法:

public String[] split(String regex);//按照参数的规则,将字符串切分成为若干部分
String str1="aaa,bbb,ccc";
String[] array1=str1.split(",");//aaa	bbb		ccc

注意:

split方法的参数其实是一个“正则表达式”,如果要按照英文句点".“进行切分,必须写”\\."(两个反斜杠)

第六节 关键字Static静态

6.1 概述

一旦使用了static关键字,那么这样的内容不再属于对象自己,而是属于类的,所以凡是本类的对象,都共享一份

6.2 static修饰成员
static String room;
6.3 static修饰方法
public void method(){
    System.out.println("这是一个普通的成员方法。");
}
public static void methodStatic(){
    System.out.println("这是一个静态方法");
}

一旦使用static修饰成员方法,那么这就成为了静态方法。静态方法不属于对象,而是属于类的

如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它

如果有了static关键字,那么不需要创建对象,直接就能通过类名称来使用它

无论是成员变量还是成员方法,如果有了static,都推荐使用类名称进行调用

推荐格式:

静态变量:类名称.静态变量

静态方法:类名称.静态方法()

注意:

1、静态只能直接访问静态,不能直接访问非静态

**原因:因为在内存中是先有静态内容,后有的非静态内容**

2、静态方法中不能用this

原因:this代表当前对象,通过谁调用的方法,谁就是当前对象

6.4 静态static的内存图

在方法区中有一块静态区,专门用来存储静态static类型

注意:根据类名称访问静态成员变量的时候,全程和对象向就没关系,只和类有关系

在这里插入图片描述

6.5 静态代码块

格式:

public class 类名称{
    static{
        //静态代码块的内容
    }
}

**特点:**当第一次用到本类时,静态代码块执行唯一的一次

注意:静态内容总是优先于非静态,所以静态代码块比构造方法先执行

静态代码块的典型用途:用来一次性地对静态成员变量进行赋值

第七节:Arrays工具类

7.1 数组工具类Arrays

java.util.Arrays是一个与数组相关的工具类,里面提供了大量静态方法,用来实现数组常见操作

常见的操作:

public static String toString(数组);//将参数数组变成字符串(按照默认格式:[元素1,元素2,...])
String intstr=Arrays.toString(intArray2);
public static String void sort(数组);//按照默认升序(从小到大)对数组的元素进行排序
Arrays.sort(array);//直接将数组排序,没有返回对应数组

注意:

1、如果是数值,sort默认按照升序从小到大排序

2、如果是字母,sort默认按照字母升序

3、如果是自定义的类型,那么这个自定义的类需要有Comparable或者Comparator接口的支持

第八节: Math类

java.utli.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作

public static double abs(double num);//获取绝对值
System.out.println(Math.abs(3.14));//3.14
System.out.println(Math.abs(0));//0
System.out.println(Math.abs(-2.5));//2.5
public static double ceil(double num);//向上取整
System.out.println(Math.ceil(2.5));//3.0
public static double floor(double num);//向下取整
System.out.println(Math.floor(2.5));//2.0
public static long round(double num);//四舍五入
System.out.println(Math.round(2.5));//3.0
Math.PI//代表近似的圆周率常量(默认为double)

第二章:继承和多态

第一节:继承

1.1:继承的概述

面向对象的三大特征:封装性、继承性、多态性

继承是多态的前提,如果没有继承,就没有多态

继承主要解决的问题是:共性抽取

**父类:**也可以叫做基类、超类

**子类:**也可以叫做派生类

继承关系中的特点:

1、子类可以拥有父类的内容

2、子类还可以拥有自己专有的新内容

1.2:继承的格式

在继承的关系中,子类就是一个父类。(子类可以被当做父类看待)

定义父类的格式:

public class 父类名称{
    //...
}

定义子类的格式:

public class 子类名称 extends 父类名称{
    //...
}
1.3:继承中成员变量的访问特点

在父子类的继承关系中,如果成员名变量重名,则创建子类对象时,访问有两种方式:

1、直接通过子类对象访问成员变量:等号左边是谁,就优先用谁,没有则向上找

2、间接通过成员方法访问成员变量:该方法属于谁,就优先用谁,没有则向上找

1.4:区分子类方法中重名的三种情况

局部变量: 直接写成员变量名

本类的成员变量: this.成员变量名

父类的成员变量: super.成员变量名

1.5:继承中成员方法的访问特点

在父子类的继承关系中,创建子类对象,访问成员方法的规则:

创建的对象是谁,就优先用谁,如果没有就向上找

注意:无论是成员方法还是成员变量,如果没有都是向上找父类,绝不会向下找子类

1.6:方法的覆盖重写

**重写概念:**在继承关系中,方法的名称一样,参数列表也一样

重写(Override):方法的名称一样,参数列表也一样覆盖、覆写

重载(Overload):方法的名称一样,参数列表不一样

**方法的覆盖重写特点:**创建的是子类对象,则优先用子类方法

注意:

1、必须保证父子类之间的方法名称相同,参数列表也相同

@Override,写在方法前面,用来检测是否是有效的方法覆盖重写

​ 这个注释就算不写,只要满足要求,也是正确的方法覆盖重写

2、子类方法的返回值必须小于等于父类方法的返回值范围

3、子类方法的权限必须大于等于父类方法的权限修饰符

权限比较:public>protected>(default)>private

(default)不是关键字,而是什么都不写

**设计原则:**对于已经投入使用的类,尽量不要进行修改,推荐定义一个新的类,来重复利用其中共性 内容,并且添加改动新内容

1.7:继承中构造方法的访问特点

继承关系中,父子类构造方法的访问特点:

1、子类构造方法中有一个默认隐含的"super()"调用,所以一定是先调用的父类构造,后执行的子类构造

2、子类构造可以通过super关键字来调用父类重载构造

3、super的父类构造调用,必须是子类构造方法的第一个语句,不能一个子类构造调用多次super构造

总结:

子类必须调用父类构造方法,不写则赠送super(),写了则用写的指定的super调用,super只能有1个,还必须是第一个

1.8:关键字super和this的用法
super关键字的用法:

1、在子类的成员方法中,访问父类的成员变量

public void methodzi(){
    System.out.println(super.num);//父类中的num
}

2、在子类的成员方法中,访问父类的方法

public void methodzi(){
    super.method();//访问父类中的method
}

3、在子类的构造方法中,访问父类的构造方法

public zi(){
    super();//可以不写
}
this关键字的用法:

super关键字用来访问父类内容,而this关键字用来访问本类内容

this关键字的用法:

1、在本类的成员方法中,访问本类的成员变量

int num=20;
public void shownum(){
    int num=10;
    System.out.println(num);//局部变量
    System.out.println(this.num);//本类中的成员变量
    System.out.println(super.num);//父类中的成员变量
}

2、在本类的成员方法中,访问本类的另一个成员方法

public void methodA(){
    System.out.println("AAA");
}
public void methodB(){
    this.methodA();
    System.out.println("BBB");
}

3、在本类的构造方法中,访问本类的另一个构造方法

注意:A this(…)调用也必须是构造方法的第一个语句,唯一一个

B super和this两种构造调用,不能同时使用

public zi(){
    this(123);//本类的无参构造,调用本类的有参构造
}
public zi(int n){
    
}
1.9:Java继承的三个特点

**1、Java语言是单继承的:**一个类的直接父类只能有唯一一个

2、Java语言可以多级继承

3、一个子类的直接父类是唯一的,但是一个父类可以拥有很多个子类

第二节:抽象类

2.1:抽象的概念

如果父类当中的方法不确定如何进行{}方法体实现,那么这就应该是一个抽象方法

2.2:抽象的方法和抽象的类的格式

**抽象方法:**加上abstract关键字,然后去掉大括号,直接分号结束

**抽象类:**抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可

public abstract class Animal{
	public abstract void eat();
}
2.3:抽象方法和抽象类的使用

如何使用抽象类和抽象方法:

1、不能直接创建new抽象类对象

2、必须用一个子类来继承抽象父类

3、子类必须覆盖重写抽象父类中所有的抽象方法

4、创建子类对象进行使用

**覆盖重写(实现):**去掉抽象方法的abstract关键字,然后补上方法体大括号

2.4:抽象方法和抽象类的注意事项

1、抽象类不能创建对象,只能创建其非抽象子类的对象

2、抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的

3、抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类

4、抽象类的子类,必须重写抽象父类中所有的抽象方法,除非子类是抽象类

第三节:接口

3.1 接口概念

**接口:**一种公共的规范标准

只要符合规范标准,大家就可以通用

接口是多个类的公共规范,是一种引用数据类型,最重要的内容就是其中的抽象方法

3.2 接口的定义基本格式

定义接口的格式:

public interface 接口名称{
    //接口内容
}

**备注:**换成了关键字interface之后,编译生成的字节码文件依然是.java–>.class

如果是java 7,那么接口中可以包含的内容有:

1、常量

2、抽象方法

如果是java 8,还可以额外包含有:

3、默认方法

4、静态方法

如果是java 9,还可以额外包含有:

5、私有方法

3.3 接口的抽象方法定义

在任何版本的Java中,接口都能定义抽象方法

格式:

public abstract 返回值类型 方法名称(参数列表);
abstract void 方法名称(参数列表);
public void 方法名称(参数列表);
void 方法名称(参数列表);

注意:

1、接口中的抽象方法,修饰符必须是两个固定的关键字:public abstract

2、这两个关键字修饰符,可以选择性的忽略

3、方法的三要素可以随意定义

3.4 接口的使用步骤

1、接口不能直接使用,必须有一个“实现类”来“实现”该接口

格式:

public class 实现类名称 implements 接口名称{
    //...
}

2、接口的实现类必须覆盖重写(实现)接口中所有的抽象方法

​ 实现:去掉abstract关键字,加上方法体大括号

3、创建实现类的对象,进行使用

注意:如果实现类没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类

3.5 接口的默认方法

从Java 8开始,接口里允许定义默认方法

格式:

public default 返回值类型 方法名称(参数列表){
    方法体
}

备注:接口中的默认方法可以解决接口升级问题

总结:

1、接口的默认方法,可以通过接口实现类对象直接调用

2、接口的默认方法,也可以被接口实现类进行覆盖重写

3.6 接口的静态方法

从Java 8开始,接口中允许定义静态方法

格式:

public static 返回值类型 方法名称(参数列表){
    方法体
}

提示:就是将abstract或者default换成static即可,带上方法体

注意:不能通过接口实现类的对象来调用接口当中的静态方法

正确用法:通过接口名称,直接调用其中的静态方法

格式:

接口名称.静态方法名(参数);
3.7 接口的私有方法

需求:我们需要抽取一个共有方法,用来解决两个默认方法之间重复代码的问题,但是这个公共方法不应该让实现类使用,应该是私有化的

从Java9 开始,接口当中允许定义私有方法

私有方法的种类:

1、普通私有方法:解决多个默认方法之间重复代码问题

格式:

private 返回值类型 方法名称(参数列表){
    方法体
}

2、静态私有方法:解决多个静态方法之间重复代码问题

格式:

private static 返回值类型 方法名称(参数列表){
    方法体
}
3.8 接口的常量定义和使用

接口当中也可以定义“成员变量”,但是必须使用public static final三个关键字进行修饰

从效果上看,这其实就是接口的**【常量】**

格式:

public static final 数据类型 常量名称=数据值;
都能用	 能.出来 不可变	
例:public static final int num=10;//这其实就是一个常量,不可以修改

注意:

1、接口当中的常量,可以省略public static final,不写也照样是这样

2、接口当中的常量,必须进行赋值,不能不赋值

3、接口当中常量的名称,使用完全大写的字母,用下划线进行分隔(推荐命名规则)

3.9 内容小结

在Java 9+版本中,接口的内容可以有:

1、成员变量其实是常量,格式:

[public] [static] [final] 数据类型 常量名称=数据值;

注意:常量必须进行赋值,而且一旦赋值不能改变,变量名称完全大写,用下划线进行分隔

2、接口中最重要的就是抽象方法,格式:

[public] [abstract] 返回值类型 方法名称(参数列表);

注意:实现类必须覆盖重写接口中所有的抽象方法,除非实现类是抽象类

3、从Java 8开始,接口里允许定义默认方法,格式:

public default 返回值类型 方法名称(参数列表){
    方法体
}

注意:默认方法也可以被覆盖重写

4、从Java 8开始,接口里允许定义静态方法,格式:

[public] static 返回值类型 方法名称(参数列表){
    方法体
}

注意:应该通过接口名称进行调用,不能通过实现类对象调用接口静态方法

5、从Java 9开始,接口里允许定义私有方法,格式:

普通私有方法:

private 返回值类型 方法名称(参数列表){
    方法体
}

静态私有方法:

private static 返回值类型 方法名称(参数列表){
    方法体
}

注意:private的方法只有接口自己才能调用,不能被实现类或别人使用

使用接口的时候,需要注意:

1、接口是没有静态代码块或构建方法的

2、一个类的直接父类是唯一的,但是一个类可以同时实现多个接口

格式:

public class MyInterfaceImp implments MyInterfaceA,MyInterfaceB{
    //覆盖重写所有抽象方法
}

3、如果实现类所实现的多个接口中,存在重复的抽象方法,那么只需要覆盖重写一次即可

4、如果实现类没有覆盖重写所有接口中的所有抽象方法,那么实现类就必须是抽象类

5、如果实现类所实现的多个接口中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写

6、一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,会优先用父类中的方法

3.10 接口之间的多继承

1、类与类之间是单继承的,直接父类只有一个

2、类与接口之间是多实现的,一个类可以实现多个接口

3、接口与接口之间是多继承的

注意:

1、多个父接口中的抽象方法如果重复,没关系

2、多个父接口中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,【而且带着default关键字】

第四节:多态

4.1 概述:

面向对象三大特征:封装性、继承性、多态性

extends继承或者implements实现,是多态性的前提

**对象的多态性:**一个对象拥有多种形态

4.2 多态的使用和说明

代码当中体现多态性,其实就是一句话:父类引用指向子类对象

格式:

父类名称 对象名=new 子类名称();
	或者:
接口名称 对象名=new 实现类名称();

访问成员变量的两种方式:

1、直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找

2、间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找

第五节:final关键字

5.1 概述

final:最终不可改变的

常见四种用法:

1、可以用来修饰一个类

2、还以用来修饰一个方法

3、还可以用来修饰一个局部变量

4、还可以用来修饰一个成员变量

5.2 final关键字用来修饰一个类

当final关键字用来修饰一个类时,格式:

public final class 类名称{
    //...
}

**含义:**当前这个类不能有任何的子类,即不能使用final类作为父类

注意:一个类如果是final类,那么其中所有的成员方法都无法进行覆盖重写

5.3 final关键字用于修饰成员方法

当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写

格式:

修饰符 final 返回值类型 方法名称(参数列表){
    //方法体
}

注意:对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾

5.4 final关键字用于修饰局部变量

一旦使用final用来修饰局部变量,那么这个变量就不能进行修改,一次赋值,终生不变

final int num=200;//不可再改变num的值了
final int numb;
numb=100;//正确写法,只要保证只有唯一一次赋值即可

不变:对于基本类型来说,不可改变的是变量当中的数据,对于引用类型来说,不可变的是变量中的地址值,但其中的数据可以改变

final Student stu2=new Student("aa");
stu2=new Student("bb");//错误写法,final的引用类型变量,其中的地址不可改变
5.5final关键字用于修饰成员变量

对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变的

1、由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了

2、对于final的成员变量,要么进行直接赋值,要么进行构造方法赋值(二者选其一)

3、必须保证类中所有重载的构造方法,都最终会对final的成员变量进行赋值

第六节:四种权限修饰符

四种权限修饰符: public>protect>(default)>private

同一个类(我自己) YES YES YES YES

同一个包(我邻居) YES YES YES NO

不同包子类(我儿子) YES YES NO NO

不同包非子类(陌生人) YES NO NO NO

第七节:内部类

7.1 内部类的概念与分类

如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类

分类:

1、成员内部类

2、局部内部类(包含匿名内部类)

7.2 成员内部类
定义格式:
修饰符 class 外部类名称{
    修饰符 class 内部类名称{
        /...
    }
    //...
}

注意:内用外,随意访问;外用内,需要借助内部类对象

如何使用:

**1、间接方式:**在外部类的方法当中使用内部类,然后main只是调用外部类的方法

Body body=new Body();
body.methodBdy();

**2、直接方式:**公式:外部类名称.内部类名称 对象名=new 外部类名称().new 内部类名称();

Body.Heart heart=new Body().new Heart();
heart.beat();
内部类的同名变量访问:

如果出现了重名现象,那么格式是:

外部类名称.this.外部类成员变量名

public class Outer{
    int num=10;
    public class Inner{
        int num=20;
        public void methodInter(){
            int num=30;//内部类方法的局部变量
            System.out.println(num);//局部变量,就近原则
            System.out.println(this.num);//内部类的成员变量
            System.out.println(Outer.this.num);//外部类的成员变量
        }
    }
}
7.4 局部内部类

如果一个类是定义在一个方法内部的,那么这就是一个局部内部类

**“局部”**只有当前所属方法才能使用它,出了这个方法外面就不能用了

定义格式:

修饰符 class 外部类名称{
    修饰符 返回值类型 外部类方法名称(参数列表){
        class 局部内部类名称{
            //...
        }
    }
}

定义一个类时,权限修饰符规则:

1、外部类:public/(default)

2、成员内部类:public/protected/(default)/private

3、局部内部类:什么都不能写

注意:局部内部类如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】

备注:从Java 8+开始,只要局部变量不变,那么关键字final关键字可以省略

原因:

1、new出来的对象在堆内存当中

2、局部变量是跟着方法走的,在栈内存当中

3、方法运行结束之后立刻出栈,局部变量就会立刻消失

4、new出来的对象会在堆内存中持续存在,知道垃圾回收消失

7.5 匿名内部类

如果接口的实现类(或者父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略该类的定义,而改写为使用**【匿名内部类】**

匿名内部类的定义:

格式:

接口名称 对象名=new 接口名称(){
  //覆盖重写所有抽象方法  
};

**对格式进行解析:**new 接口名称(){…}

1、new代表创建对象的动作

2、接口名称就是匿名内部类需要实现哪个接口

3、{…}这才是匿名内部类的内容

注意:

1、匿名内部类,在【创建对象】时,只能使用唯一一次。

如果希望多次创建对象,而且类的内容一样,那么必须使用单独定义的实现类

2、匿名对象,在【调用方法】的时候,只能调用唯一一次

如果希望同一个对象调用多次方法,那么就必须给对象起个名字

3、匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略【对象名称】

强调:匿名内部类和匿名对象不是一回事

第三章:常用的API第二部分

第一节:Object类

Object类的equals方法

Person类默认继承了Object类,所以可以使用Object类的equals方法

boolean equals(Object obj)指示其他某个对象是否与此对象“相等”

参数:Object obj :可以传递任意的对象

obj:传递过来的参数

基本数据类型:比较的是

引用数据类型:比较的是两个对象的地址值

哪个对象调用的方法,方法中的this就是那个对象

重写Object类的equals方法:

Object类的equals方法,默认比较的是两个对象的地址值,没有意义,所以我们要重写equals方法,比较两个对象的属性。问题:隐含着一个多态

**多态的弊端:**无法使用子类特有的内容(属性和方法)

**解决弊端的方法:**可以使用向下转型(强转),把obj类型转换为Person

//增加一个判断,传递的参数obj如果是this本身,直接返回true,提高程序的效率
if(obj==this)
    return true;

//增加一个判断,传递的参数obj如果是null,直接返回false,提高程序的效率
if(obj==null)
    return false;

if(obj instanceof Person){
    Person p=(Person)obj;//强转
	//比较两个对象的属性,一个对象是this(p1),一个对象是p(obj->p2)
	this.name.equals(p.name)&&this.age==p.age;//true
}
//不是Person类型
return flase;
Objects类的equals方法:

Objects类的equals方法:对两个对象进行比较,防止空指针异常

第二节:Date类

2.1 毫秒值的概念和作用

需要导包:java.util.Date :表示日期和时间的类,精确到毫秒

**毫秒:**千分之一秒

**毫秒的作用:**可以对时间和日期进行计算

可以把日期转换为毫秒进行计算,计算完毕,再把毫秒转换为日期

**时间原点:**1970年1月1日00:00:00(英国格林威治)

System.out.println(System.currentTimeMillis());//获取当前系统时间到时间原点经历了多少毫秒(Long类型的值)

注意:中国属于东八区,会把时间增加8个小时

把毫秒转换为日期:1天=246060=86400秒=86400000毫秒

2.2 Date类的构造方法和成员方法

Date类的空参数构造方法:

Date()获取当前系统的日期和时间

Date date=new Date();
System.out.println(date);//Sun Dec 06 19:29:24 CST 2020

Date类的带参数构造方法:

Date(Long date):传递毫秒值,把毫秒值转化为Date日期

Date date1=new Date(0L);
System.out.println(date1);//Thu Jan 01 08:00:00 CST 1970

**getTime()😗*把日期转换为毫秒值(相当于System.currentTimeMills()方法),返回自1970年1月1日00:00:00 GNT 以来Date对象表示的毫秒数

Date date2=new Date();
long time=date2.getTime();
System.out.println(time);//1607261977925
2.3 DateFormat类

功能:对日期进行格式化,是日期/时间格式化子类的抽象类

作用:格式化(也就是日期–>文本)、解析(文本–>日期)

导包java.text.DateFormat

成员方法:

String format(Date date) 按照指定的模式,把Date日期,格式化为符合模式的字符串
    使用步骤:
    1、创建SimpleDateFormat对象,构造方法中传递指定的模式
    2、调用SimpleDateFormat对象中的方法format,按照构造方法中指定的模式,把Date日期格式化为符合模式的字符串(文本)
Date parse(String source) 把符合模式的字符串,解析为Date日期
    使用步骤:
    1、创建SimpleDateFormat对象,构造方法中传递指定的模式
    2、调用SimpleDateFormat对象中的方法parse,把符合构造方法中模式的字符串,解析为Date日期
    注意:
    	prase方法中声明了一个异常叫ParseException,如果字符串和构造方法的模式不一样,那么程序就会抛出异常,调用一个抛出了异常的方法,就必须处理这个异常,要么throws继续抛出这个异常要么try catch自己处理

DateFormat类是一个抽象类,无法直接创建对象使用,可以使用DateFormat类的子类

构造方法:

SimpleDateFormat(String pattern)
    用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat
参数:String pattern---传递指定的模式,区分大小写
    y	年		M	月		d	日		H	时		m	分		s	秒
    "yyyy-MM-dd HH:mm:ss"
注:模式中的字母不能更改,连接符号可以改变

第三节:Calendar类

Canlendar类是一个抽象类,里面提供了很多操作日历字段的方法(Year、Month、Day_Of_Month、Hour),它无法直接创建对象使用,里面有一个静态方法叫getInstance(),该方法反回了Canlendar类的子类对象

java.util.Calendar类:日历类

常用方法:
public int get(int field):返回给定日历字段的值
public void set(int field,int value):将给定的日历字段设置为给定值
public abstract void add(int field,int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量
public Date getTime():返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)Date对象
    成员方法的参数:
    	int field:日历类的字段,可以使用Calendar类的静态成员变量获取
    	int value:给指定字段设置的值

第四节:System类

java.lang.System

提供了大量的静态方法,可以获取与系统相关的信息或系统级操作,在System类的API文档中,常用的方法有:

public static long currentTimeMills():返回以毫秒为单位的当前时间
    格式:
    long s=System.currentTimeMillis();
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length):将数组中指定的数据拷贝到另一个数组中
    参数:src:原数组	srcPos:原数组中的起始位置(起始索引)	dest:目标数组	
         destPos:目标数据中的起始位置		length:要复制的数组元素的数量
    格式:int[] src={1,2,3,4,5};
         int[] dest={6,7,8,9,10};
		 System.arraycopy(src,0,dest,0,3);

第五节:StringBuilder类

5.1 StringBuilder的原理

由于String类的对象内容不可改变,所以每当进行字符串拼接时,总是会内存中创建一个新的对象。

字符串是常量,它们的值在创建之后不可更改,它的底层是一个被final修饰的数组,不能改变

public class StringDemo{
    public static void main(String[] args){
        String s="Hello";
        s+="World";
        System.out.println(s);
    }
}

进行字符串的相加,内存中就会有多个字符串,占用空间多,效率低下

**StringBuilder类:**字符串缓冲区,可以提高字符串的操作效率(看成一个长度可以变化的字符串),底层也是一个数组,但是没有被final修饰,可以改变长度

StringBuilder在内存中始终是一个数组,占用空间少,效率高,如果超出了StringBuilder的容量,会自动扩容

5.2 StringBuilder的构造方法
StringBuilder():构造一个不带任何字符的字符串生成器,其初始容量为16个字符
    //空参数构造方法
    StringBuilder str=new StringBuilder();
    System.out.println(str);//空

    //带字符串的构造方法
    StringBuilder str1=new StringBuilder("abc");
    System.out.println(str1);//abc
5.3 StringBuilder的成员方法
public StringBuilder append(..):添加任意类型数据的字符串形式,并返回当前对象自身
    使用append方法不需要接收返回值
    StringBuilder str=new StringBuilder();
    StringBuilder str2=str.append("abc");
    System.out.println(str);//abc
    System.out.println(str2);//abc
    System.out.println(str==str2);//true
    str.append(1).append(true).append(8.8).append("中");
    System.out.println(str);//abc1true8.8中

public String toString():将当前StringBuilder对象转换为String对象
    String str="hello";
	//字符串转化为StringBuilder
    StringBuilder bu=new StringBuilder(str);
    bu.append("world");
	//StringBulider转换为字符串
    String str2=bu.toString();

第六节:包装类

6.1 概述

java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果我们想要我们的基本类型像对象一样操作,就可以使用基本类型对象的包装类

**包装类:**基本数据类型,使用起来非常方便,但是没有对应的方法来操作这些基本类型的数据,可以使用一个类,把基本类型的数据装起来,这个类叫做包装类。我们可以使用类中的方法来操作这些基本类型的数据

6.2 装箱与拆箱

**装箱:**从基本类型转换为对应的包装类对象(基本类型的数据—>包装类)

**拆箱:**从包装类对象转换为对应的基本类型(包装类—>基本类型的数据)

装箱构造方法:

Integer(int value):构造一个新分配的Integer对象,它表示指定的intInteger in1=new Integer(1);//方法上有横线,说明方法过时了
    System.out.println(in1);//1	重写了toString方法
Integer(String s):构造一个新分配的Integer对象,它表示String参数所指示的int值,传递的字符串,必须是基本类型的字符串,否则会抛出异常,"100"正确,"abc"错误
    Integer in2=new Integer("1");
    System.out.println(in2); //1

装箱静态方法:

static Integer valueOf(int i):返回一个表示指定int值的Integer实例
    Integer in3=Integer.valueOf(1);
    System.out.println(in3);//1
static Integer valueOf(String s):返回保存指定的String的值的Integer对象
    Integer in3=Integer.valueOf("1");
    System.out.println(in3);//1

拆箱成员方法:

int intvalue():int类型返回该Integer的值
    int i=in1.intValue();
    System.out.println(i);//1
  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值