接口
定义:接口其实就是代码的一种规范。JDK8之前接口中只能是抽象方法和常量,没有其他成分了。接口不能实例化,接口中的成员都是public修饰,写不写都是,因为规范的目的是为了公开化。
格式:
// 接口用关键字interface来定义
public interface 接口名 {
// 常量
// 抽象方法
}
用法:接口是用来被类实现(implements
)的,实现接口的类称为实现类。实现类可以理解成所谓的子类。
// 实现的关键字:implements
修饰符 class 实现类 implements 接口1, 接口2, 接口3 , ... {
// 重写抽象方法
}
- 从上面可以看出,接口可以被类单实现,也可以被类多实现,接口不能创建对象
类、接口之间的关系:
- 类和类之间的关系:单继承
- 类和接口之间的关系:多实现
- 接口和接口之间的关系:多继承,一个接口可以同时继承多个接口
接口多继承的作用:规范合并,整合多个接口为同一个接口,便于子类实现
JDK8开始接口新增的方法
作用:防止项目开发时需要对接口丰富,加入新的抽象方法。此时若没有新增的方法就要所有实现类实现这些方法,而引入新增的方法可以在丰富接口功能的同时又不对子类代码进行更改。
默认方法:类似之前写的普通实例方法:必须用default修饰。默认会用public修饰,需要用接口实现类的对象来调用
default void run(){
System.out.println("--开始跑--");
}
静态方法:默认会public修饰,必须static修饰。接口的静态方法必须用本身的接口名来调用
static void inAddr(){
System.out.println("我们在学习Java!");
}
私有方法:私有的实例方法,必须用private修饰,从JDK 1.9才开始有的,只能接口中被其他默认方法或者私有方法访问。
private void go(){
System.out.println("--准备--");
}
JDK8新增的3种方法我们自己在开发中很少使用,通常是Java源码涉及到的,我们需要理解、识别语法、明白调用关系即可
注意事项:
- 一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类
- 一个类实现多个接口,多个接口的规范不能冲突
- 一个类实现多个接口,多个接口中有同样的静态方法不冲突。
- 一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。
- 一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
- 一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。
内部类
定义:内部类就是定义在一个类里面的类,里面的类可以理解成”寄生“,外部类可以理解成”宿主“
使用场景:当一个事物的内部还有一个部分需要一个完整的结构进行描述时
基本作用:
内部类通常可以方便访问外部类的成员,包括私有的成员。
内部类提供了更好的封装性,内部类本身就可以用private ,protectecd等修饰,封装性可以做更多控制
类别:静态内部类、成员内部类、局部内部类、匿名内部类(重点)
静态内部类
定义:有static修饰,属于外部类本身。它的特点和使用与普通类是完全一样的,类有的成分他都有,只是位置在别人里面而已。
public class Outer{
// 静态成员内部类
public static class Inner{
}
}
创建对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类构造器();
如:Outer.Inner in = new Outer.Inner();
注意:
- 静态内部类中可以直接访问外部类的静态成员,因为外部类的静态成员只有一份可以被共享访问。
- 但不能直接访问外部类的实例成员,因为外部类的实例成员必须用外部类的对象访问
成员内部类
定义:无static修饰,属于外部类的对象。JDK16之前,成员内部类中不能定义静态成员,JDK16开始也可以定义静态成员了。
public class Outer {
// 成员内部类
public class Inner {
}
}
创建对象的格式:外部类名.内部类名 对象名 = new 外部类构造器.new 内部类构造器();
如:Outer.Inner in = new Outer().new Inner();
注意:
- 成员内部类中可以直接访问外部类的静态成员,因为外部类的静态成员只有一份可以被共享访问。
- 成员内部类的实例方法中也可以直接访问外部类的实例成员,因为成员内部类必须先有外部类对象,才能有成员内部类对象,因此能访问。
- 在成员内部类中访问所在外部类对象,格式:
外部类名.this
,如下面代码
class People{
private int heartbeat = 150;
public class Heart{
private int heartbeat = 110;
public void show(){
int heartbeat = 78;
System.out.println(heartbeat); // 78
System.out.println(this.heartbeat); // 110
System.out.println(People.this.heartbeat); // 150
}
}
}
局部内部类:放在方法、代码块、构造器等执行体中。局部内部类的类文件名为:外部类$N内部类.class
匿名内部类(重点)
定义:本质上是一个没有名字的局部内部类。
作用:方便创建子类对象,最终目的是为了简化代码编写
格式:
new 类|抽象类名|或者接口名() {
重写方法;
};
// 如:
Employee a = new Employee() {
public void work() {
}
};
a. work();
特点:
匿名内部类是一个没有名字的内部类,同时也代表一个对象
匿名内部类产生的对象 类型,相当于是当前new类型的子类类型
匿名内部类通常是在开发中调用别人的方法时,别人需要我们写的时候才会定义出来使用
API
定义:API的全称是Application Programming Interface,应用程序编程接口。其实就是Java写好的功能代码,可以直接调用
Object类
一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类
Object作为所有类的父类,提供了很多常用的方法给每个子类对象拿来使用
常用方法:
方法名 | 说明 |
---|---|
public String toString() | 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址 |
public boolean equals(Object o) | 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false |
注意:
- 父类toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息
- 父类equals()方法存在的意义也是为了被子类重写,以便子类自己来定制比较规则(如比较对象内容)
Objects
- Objects是一个工具类,提供了一些方法去完成一些功能
常用方法:
方法名 | 说明 |
---|---|
public static boolean equals(Object a, Object b) | 比较两个对象的,底层会先进行非空判断,从而可以避免空指针异常。再进行equals比较 |
public static boolean isNull(Object obj) | 判断变量是否为null ,为null返回true ,反之 |
注意:官方在进行字符串比较时,没有用字符串对象的的equals方法,而是选择了Objects的equals方法来比较,因为使用Objects的equals方法在进行对象的比较会更安全。
StringBuilder
- StringBuilder是一个可变的字符串的操作类,我们可以把它看成是一个对象容器
- 使用StringBuilder的核心作用:操作字符串的性能比String要更高(如拼接、修改等)
- 最终要用
toString()
方法转为String类型
构造器
名称 | 说明 |
---|---|
public StringBuilder() | 创建一个空白的可变的字符串对象,不包含任何内容 |
public StringBuilder(String str) | 创建一个指定字符串内容的可变字符串对象 |
常用方法
方法名称 | 说明 |
---|---|
public StringBuilder append(任意类型) | 添加数据并返回StringBuilder对象本身 |
public StringBuilder reverse() | 将对象的内容反转 |
public int length() | 返回对象内容长度 |
public String toString() | 通过toString()就可以实现把StringBuilder转换为String |