包
1.包就是文件夹。用来管理各种不同功能的Java类,方便后期代码维护。
2.包名规则:公司域名反写 + 包的作用(还是看实际情况),需要全部英文小写,见名知意。比如com.xxxxxx.calculate,如果calculate下面有一个类,名为 Addition ,那么com.xxxxxx.calculate.Addition就称为Addition类的全类名(Addition是随便起的类名)
3.使用其它类时,需要使用全类名,但是可以通过import文件的前边部分(com.xxxxxx.calculate),当使用类的时候就可以直接通过类名去使用了
4.使用其他类的规则:
- 使用同一个包中的类时,不需要导包(系统会默认到本包里面去找)
- 使用java.lang包中的类时,不需要导包
- 其他情况都需要导包
- 如果同时使用两个包中的同类名,需要用全类名
final
1.final修饰方法,表明该方法是最终方法,不能被重写。一般在该方法作为一种规则的时候会用到。(了解一下)
2.final修饰类,表明该类是最终类,不能被继承。
3.final修饰变量,则其叫做常量,只能被赋值一次。实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性。常量的命名规范:
- 单个单词:全部大写
- 多个单词:全部大写,单词之间用下划线隔开
4.用final修饰的变量是基本数据类型时,变量存储的数据值不能发生改变;如果final修饰的变量时引用数据类型时,变量存储的地址值不能发生改变,对象内部的内容可以改变(String创建后不能发生改变就是因为在String内部对应字符串内容的方法被final和private一起修饰了,因此无法字符串创建后就无法发生改变)。
5.常量的应用场景:可以在while或者switch语句里面,对于特定的选择(1,2,3,4)进行常量化命名 例如 private static final int ADD_STUDENT = 1;这样能大大提高代码的阅读性
权限修饰符
1.权限修饰符:是用来控制一个成员能够被访问的范围的。
2.可以修饰成员变量,方法,构造方法和内部类。
3.权限修饰符的分类:
修饰符 | 同一个类中 | 同一个包中其他类 | 不同包下的子类 | 不同包下的无关类 |
private | ✔ | |||
默认(空着不写) | ✔ | ✔ | ||
protected | ✔ | ✔ | ✔ | |
public | ✔ | ✔ | ✔ | ✔ |
4.实际开发中更多实用private和public,场景:
- 成员变量私有
- 方法公开
- 如果一个方法相当于一个功能只被该类中其他方法调用,那么这个方法一般也私有
代码块
1.使用{}括住的就是代码块。代码块有三类:
- 局部代码块:写在方法里的,直接用{}括起来的,用于提前结束变量生命周期的(已淘汰)
- 构造代码块
- 静态代码块
2.构造代码块:
- 写在成员位置的代码块(直接用{}括住代码);
- 作用:可以把多个构造方法中重复的代码抽取出来;
- 执行时机:在创建本类对象的时候会先执行构造代码块再执行构造方法;
- 慢慢地被淘汰了,因为不够灵活。
3.静态代码块:
- 格式:static{}
- 特点:需要通过static关键词修饰,随着类的加载而加载,并且自动触发、只执行一次
- 使用场景:在类加载的时候,做一些数据初始化的时候使用
抽象类
1.在继承里面,如果有一些父类中的方法是要求子类一定要去重写的,可以通过abstract关键字去进行修饰,而abstract关键字所在的类就是抽象类。
2.抽象方法:将共性的行为(方法)抽取到父类之后,由于每一个子类执行的内容是不一样的,所以,在父类中不能确定具体的方法体,该方法就可以定义为抽象方法。
3.抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类。
4.抽象方法定义格式:public abstract 返回值类型 方法名(参数列表);(直接分号结束)
5.抽象类的定义格式:public abstract class 类名{}
6.抽象类和抽象方法的注意事项:
- 抽象类本身不能实例化(创建对象),但抽象类的子类可以
- 抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类
- 抽象类可以有构造方法
- 抽象类的子类要么重写抽象类中所有的抽象方法,要么本身也是抽象类
7.抽象类的作用:抽取共性时,如果无法确定方法体,就把方法定义为抽象的,抽象类会强制让子类按照某种格式重写。
接口
1.接口就是一种规则,是对行为的抽象。
2.接口的定义和使用:
- 接口用关键字interface定义,规则: public interface 接口名{}
- 接口不能实例化
- 接口和类之间是实现关系,通过implements关键字表示:public class 类名 implements 接口名{}
- 接口的子类(实现类):要么重写接口中的所有抽象方法,要么本身是抽象类
- 一个实现类可以实现一个或者多个接口,也可以在继承一个类的同时实现多个接口: public class 类名 extends 父类 implements 接口名1,接口名2{}
3.接口中成员的特点:
- 成员变量:只能是常量,默认修饰符:public static final
- 接口中没有构造方法
- 成员方法:JDK7以前,接口中只能定义抽象方法,默认修饰符:public abstract,JDK8中接口就可以定义有方法体的方法,在JDK9及以后接口中可以定义私有方法
4.接口和类的关系:
- 类和类的关系:继承关系,只能单继承,不能多继承,但是可以多层继承
- 类和接口的关系:实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口。如果一个类实现了多个接口,并且多个接口之间有同名的方法名,那么只需要重写一次同名的方法就会被视作同时重写了多个接口中重名的方法。
- 接口和接口的关系:继承关系,可以但继承,也可以多继承,如果实现类实现了子接口的话,那就要重写子接口及其所有父类的所有方法。
JDK8以后接口中新增的方法:
1.允许在接口中定义默认方法,默认方法中允许有代码体,需要使用关键字default修饰。
2.作用:解决接口升级问题(有了其他规则)
3.接口中默认方法的定义格式:public default 返回值类型 方法名(参数列表){]
4.接口中默认方法的注意事项:
- 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字;
- public可以省略,default不能省略;
- 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写(因为如果不重写,在创建了实现类,使用实现类调用默认方法的时候就不知道调用的是哪个接口中的默认方法)。
5.允许在接口中定义静态方法,需要用static修饰,静态方法不允许被重写,可以直接通过接口名去调用接口中的静态方法。
6.接口中静态方法的定义格式:public static 返回值类型 方法名(参数列表){}
7.接口中静态方法的注意事项:
- 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
- public可以省略,static不能省略
JDK9新增的方法
1.当接口中的方法中的代码有重复的时候,一般是会再写一个方法去提取这部分的重复代码,当用到这部分重复代码时直接调用新写的方法就可以,但是这个方法一般不需要被外界访问,最好是私有的,因此在JDK9里面就允许了接口中的私有方法。
2.接口中私有方法的定义格式:
- 给默认方法服务:格式1:private 返回值类型 方法名(参数列表){} 注意:这里面的default已经不用再去写了
- 给静态方法服务:格式2:private static 返回值类型 方法名(参数列表){}
接口的应用
1.接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了。
2.当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种行为称之为接口多态。(跟继承的多态基本上是一样的) eg:接口类型 j = new 实现类对象();
适配器设计模式
1.设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类鳊木地、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
2.简单理解:设计模式就是解决问题的各种套路。
3.适配器设计模式:解决接口与接口实现类之间的矛盾问题。
4.当一个接口中抽象方法过多,但是实际只要使用其中一部分的时候,就可以使用适配器设计模式。
5.书写步骤:
- 编写中间类XXXAdapter,实现对应的接口
- 对接口中的抽象方法进行空实现(就是重写的方法体中啥也没有)
- 让真正的实现类继承中间类,并重写需要用的方法
- 为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰
内部类
1.类的五大成员:属性、方法、构造方法、代码块、内部类。
2.在类A的里面再定义一个类B,类A就叫做外部类,类B就被称之为内部类。
3.内部类出现场景:内部类表示的事物时外部类的一部分,内部类单独出现没有任何意义。
4.内部类的访问特点:
- 内部类可以直接访问外部类的成员,包括私有。
- 外部类要访问内部类的成员必须创建对象。
5.内部类的分类:成员内部类,静态内部类,局部内部类,匿名内部类
6.成员内部类:
- 写在成员位置的,属于外部类的成员(跟其它成员一样能被修饰符修饰,但不是被static修饰)。
- 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
- 获取成员内部类对象方式一:在外部类中编写方法,对外提供内部类的对象。
- 获取成员内部类对象方式二:直接创建格式:外部类名.内部类名 对象名 = new 外部类对象.new 内部类对象;
7.静态内部类:
- 严格来说静态内部类是成员内部类的一种(就是加了static)
- 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建外部类对象
- 创建静态内部类对象格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
- 调用静态内部类中非静态方法的格式:先创建内部类对象,用内部类对象调用
- 调用静态内部类中静态方法的格式:外部类名.内部类名.方法名();
8.局部内部类:
- 将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量
- 外界是无法直接使用,需要在方法内部创建对象并使用
- 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
9.匿名内部类,前三种都是了解一下,匿名内部类用的比较多,因此需要重点掌握。
- 匿名内部类本质上就是隐藏了名字的内部类
- 内部类由三个部分:1.继承/实现关系;2.方法的重写;3.创建对象
- 格式:包含了继承或实现,方法重写,创建对象。整体就是一个类的子类对象或者接口的实现类对象。
/*
格式:new 类名或者接口名(){
重写方法;
};
*/
//整体可以为Inter接口的实现类对象
//接口多态
Inter = new Inter(){
public void show(){
}
};
- 实际上的内部类是花括号里面的内容,new的也是花括号中内容
- 内部类会有自己的字节码文件,匿名内部类的字节码文件是系统自动命名
- 应用场景:当方法的参数是接口或者类时,以接口为例,可以传递这个接口 的实现类对象,如果实现类只要使用一次,就可以用匿名内部类简化代码。
- 实际上匿名内部类就是创建了 一个对象,可以链式编程