一、抽象类
抽象类:指的是一个类中没有包含足够的信息来描述具体的对象
1.抽象类
1.1 语法形式:abstract
用abstract关键字修饰类
public abstract class 类名{
//成员变量
//成员方法
//抽象方法
}
2.抽象方法
用abstract关键字修饰方法
2.1 语法形式:abstract
public abstract class 类名{
public abstract void 方法名();
}
- 抽象方法:抽象方法没有方法体
3.抽象类的注意事项
3.1 抽象类不能被实例化

3.2 抽象类可以发生向上转型

3.3 抽象类必须被继承,并且抽象方法也必须被重写

3.4 抽象类未被继承和重写
如果抽象类没有被继承,那么子类也要用abstract关键字修饰子类,一旦一个类继承了子类,那么这个类就要重写父类所有未被重写的方法

3.5 抽象方法不能被private修饰
如果抽象方法被private修饰,表明只能在该类中使用
3.6 抽象方法不能被 final 和 static 修饰
一旦抽象方法被 final 和 static 修饰 ,则子类无法重写
3.7 抽象方法一定是抽象类,但抽象类中不一定有抽象方法
抽象类中可以只有成员变量的成员方法,一旦有了抽象方法,那么这个类就一定是抽象类
二、接口
1.接口
在Java中,接口可以看成是,多个类的公共规范,是一种引用数据类型
1.1 语法形式:interface关键字
public interface 接口名{
//成员变量默认形式:public static final
//成员方法默认形式:public abstract
}
- 接口名:接口的命名一般以大写字母 I 开头
- 成员变量:创建时(public static final)不用写,但变量要初始化
- 成员方法:创建时(public abstract)不用写,但都是抽象方法,需要被重写
2.接口使用
接口不能直接使用,必须要有一个类来实现接口,从而实现接口中的所有抽象方法
2.1 语法形式:implements
public class 类名 implements 接口名{
//重写接口的方法
}
如图:

3.接口的注意事项
3.1 接口不能实例化

3.3 接口可以发生向上转型(前提是:类实现了接口)

3.2 接口的成员变量必须初始化

3.3 接口中不能有静态代码块和构造方法

3.4 接口的方法只能被public访问限定符修饰(在Java 7及以前)

(1)Java 9及以后接口方法可以是 public 和 private
4.类与接口的注意事项
4.1 接口中的方法不能再接口中实现,只能由接口的类来实现
4.2 类如果没重写接口的方法,则该类需设置为抽象类

(1)一旦抽象类被继承了,则子类需要重写所有类的抽象方法

5.多接口的实现
在Java中,类和类是单继承的,一个类只有一个父类,但一个类可以实现多个接口,从而让我们忽略继承关系的类型

- 注:实现多个接口,类必须把要实现的接口全都重写
6.接口之间的继承
在Java中,类和类之间是单继承的,一个类可以实现多个接口,那么接口和接口之间可以多继承
6.1 实现接口之间继承的关键字:extends
如图:

(1)如果一个类要实现这个被继承的接口(IAmphibious),那么这个类则要重写继承接口的所有方法

7.抽象类与接口的区别
| 1 | 结构组成 | 成员变量、方法 + 抽象方法 | 抽象方法 |
| 2 | 初始化 | 就地、构造方法 | 就地 |
| 2 | 权限 | 各种权限 | public、private |
| 3 | 子类实现方式 | 使用extends关键字继承抽象类 | 使用implements关键字实现接口 |
| 4 | 关系 | 一个抽象类能实现多个接口 | 接口不能继承抽象类,但是接口可以使用extends关键字继承多个接口 |
| 5 | 子类限制 | 一个子类只能继承一个父类 | 一个子类可以实现多个接口 |
三、接口使用实例
1.comparable接口
comparable是Java自带的比较某个对象之间大小的接口

- T :指的是泛型参数,代表比较的对象的类型
- int:表示方法返回的类型
- compareTo:表示抽象方法,要实现重写
- T o:表示要比较的对象
1.1 比较方式
该方法用于比较当前对象(this)与参数对象 o 的大小关系
如图:用comparable比较对象的年龄之间的大小

1.2 comparable的缺点
(1)侵入性强:只能比较一次,当比较完之后,再进行比较的话,则要修改类中重写的方法,且上次比较也作废了
(2)耦合度高:类中既负责数据存储,又负责排序比较,不符合单一职责原则
这些缺点能不能用其他方式来解决呢?
答案:可以,使用Comparator接口
2.Comparator接口
Comparator是外部比较器,不需要修改类的源码,还可以定义多种排序规则

- int :方法返回类型
- compare:抽象方法,需要实现重写
- o1与o2:代表两个对象
2.1 比较方式
(1)比较 o1 与 o2 的大小关系

(2)特殊比较String类型的大小
String通过实现comparable接口,来进行比较字符串之间的大小

那么可以通过compareTo方法进入String类中直接比较

3.Clonable接口
Clonable接口是一个空接口,意味着里面没有抽象方法,作用是标记当前类的对象可以被克隆

3.1 克隆方式
(1)第一步:类中实现Clonable接口,并调用Object的克隆方法

(2)第二步:处理异常
Object.clone() 声明抛出异常

- 处理方式:在调用方法中加上throwsCloneNotSupportedException

(3)第三步:调用克隆方法时,需要发生向下转型
object的克隆方法返回类型是object,object是所有类的父类,因此需要发生强制转换才能实现调用

3.1 浅拷贝
当类中有多个实例化对象时,用浅拷贝的方式只会复制基本数据类型和引用地址,不复制引用指向的对象,造成原对象和克隆对象的引用类型成员指向同一堆内存,修改一方引用对象,另一方同步变换

(1)浅拷贝方式

3.2 深拷贝
深拷贝拷贝的是:基本类型 + 所有引用类型对象,全部独立复制,互不干扰

(1)深拷贝方式

四、内部类
内部类指的是可以将一个类放在另一个类或者方法的内部,内部类分为:实例内部类、静态内部类、局部内部类(本地内部类)、匿名内部类这四种
1. 实例内部类
1.1 实例内部类对象的实例化
外部类名 变量名1 = new 外部类名();
外部类名.内部类类名 变量名2 = 变量名1.new 内部类类名();
如图所示:

1.2 访问内部类与外部类的成员
(1)内部类访问外部类成员
内部类可以访问外部类任意限定修饰符修饰的成员

(2)内部类与外部类成员不同名
内部类能够直接访问所有的成员,访问方式:输入成员

(3)内部类与外部类成员同名
访问方式:优先访问内部类

(4)当内部类与外部类成员相同时,访问外部类
访问外部类的方式:外部类名.this.成员

(5)外部类访问内部类成员
访问方式:首先,创建内部类对象,再进行访问

2.静态实例类
在类的声明加上static关键字
2.1 语法形式
static class 类名{
//成员变量和方法
}
2.2 静态内部类对象的实例化
外部类类名.内部类类名 变量名 = new 外部类类名.内部类类名();

2.3 访问静态内部类与外部类的成员
(1)访问静态内部类成员
访问方式:直接访问

(2)静态内部类只能访问外部静态成员

(4)如果一定要访问外部非静态成员
访问方式:首先,创建外部对象,再以外部对象的引用+点号+成员来访问

3.局部内部类(本地内部类)
3.1 语法形式
//外部类成员方法
public void 成员方法(){
//内部类
class 类名{
//成员变量和方法
}
}
- 局部内部类:类不能被public、static等修饰符修饰
3.2 局部内部类的访问方式
局部内部类只能在方法体中访问

4.匿名内部类
匿名内部类是Java中⼀种特殊的嵌套类,它没有类名,在声明的同时完成实例化。匿名内部类通常⽤于创建只需使⽤⼀次的类
4.1 语法形式
new SuperType(constructor-arguments) {
// 类体
};
- SuperType:可以是接口、抽象类或具体类
4.2 充当继承关系的匿名内部类

4.3 匿名内部类来充当实现接口的类

4.4 匿名内部类的访问方式
(1)访问外部类成员
可以访问外部类任意限定修饰符修饰的成员
(2)访问外部类成员变量
当访问外部成员变量时,外部成员成员变量会默认一个final(关键字),内部类访问时,不得修改变量值

(3)被static修饰的成员也只能定义一次

4.5 匿名内部类的调用方式
(1)实例化匿名内部类对象,通过对象的引用来访问

(2)将匿名内部类看成一个对象
访问方式:内部类.成员

5.Object类
Object是Java默认提供的一个类,所有类默认继承Object类。即所有类的对象都可以使用Object的引用进行接收
5.1 Object类定义好的一些方法
(1)获取对象信息

(2)对象比较
在Java中,== 进行比较时:
(1)如果 == 左右两侧是基本类型变量,比较的是变量中的值是否相等
(2)如果==左右两侧是引用数据类型变量,比较的是引用变量地址是否相同
(3)如果比较对象的内容,必须重写Object中的equals方法

(3)重写equals方法

(4)hashcode方法
该方法是一个native方法,底层是由C/C++代码写的,看不到具体的代码
hashcode方法作用:用来确定对象在内存中存储的位置是否相同,如果两个对象是一样的,那么这两个对象的hashcode的值是一样的

(5)调用Object的hashcode方法,两个对象的hashcode值不一样

(6)重写hashcode,两个对象的hashcode值一样






