内容纲要
接口比抽象类更抽象,封装了一系列抽象方法。接口中不可以存在普通方法,但是从
JDK8
之后可以有默认方法和静态方法,JDK9
之后有私有方法。
接口
接口的方法默认是抽象方法
public abstract
建议不写,简化代码。接口使用关键字interface
来定义,接口和抽象类一样不可实例化,用implements
来实现接口。
定义
接口可以多继承多级接口,并且也可以多实现。
USBService.java
public interface USBService {
void show();
//默认方法
default void recharge(){
System.out.println("充电");
}
//静态方法
static void insert(){
System.out.println("插入USB接口");
}
//私有方法
private void getType(){
System.out.println("获取USB类型");
}
}
USBServiceImpl.java
public class USBServiceImpl implements USBService{
@Override
public void show() {
}
}
- 实现类必须重写普通抽象方法
- 默认方法实现类可重写也可以不重写,实现类也可以可以调用。
- 静态方法实现类不能重写,接口可以直接调用。
- 私有方法供默认方法或静态方法调用。
- 接口里的常量默认为
public static final
,方法为public abstract
。
多态
父类引用子类的对象,同一个类型具有不同表现方式。
定义
必须通过
extends
继承或implements
实现,格式为父类名或接口名 对象名 = new 子类名或实现类名(参数列表);
USBService.java
public interface USBService {
//接入设备
void open();
//退出设备
void close();
}
DiskUSBImpl.java
public class DiskUSBImpl implements USBService {
@Override
public void open() {
System.out.println("读取硬盘设备");
}
@Override
public void close() {
System.out.println("关闭硬盘设备");
}
}
CameraUSBImpl.java
public class CameraUSBImpl implements USBService{
@Override
public void open() {
System.out.println("打开摄像头");
}
@Override
public void close() {
System.out.println("关闭摄像头");
}
}
Computer.java
public class Computer {
public void powerOn(){
System.out.println("打开电脑");
}
public void useDevice(USBService usbService){
System.out.println("使用设备");
usbService.open();
usbService.close();
}
public void powerOff(){
System.out.println("关闭电脑");
}
}
Main.java
public class Main {
public static void main(String[] args) {
Computer computer = new Computer();
USBService disk = new DiskUSBImpl();
USBService camera = new CameraUSBImpl();
/*
打开电脑
使用设备
读取硬盘设备
关闭硬盘设备
关闭电脑
*/
computer.powerOn();
computer.useDevice(disk);
computer.powerOff();
/*
打开电脑
使用设备
打开摄像头
关闭摄像头
关闭电脑
*/
computer.powerOn();
computer.useDevice(camera);
computer.powerOff();
}
}
转型
子类创造实例时,可以用父类引用,进行向上转型把子类变为更抽象的父类。父类具有的非私有方法子类都有,但是只能使用与父类相同的方法。
Pet pet = new Cat();
把父类类型强制转型为子类类型就是向下转型,向下转型可以将向上转型后的对象还原,如果原来这个对象就不是还原后的类型通常会报
ClassCastException
异常。
Cat cat = (Cat)new Pet();
内部类
一个类内部包含另一个类,编译生成的class文件有两个
外部类.class
、外部类$内部类.class
。
修饰符 class 外部类名称{
修饰符 class 内部类名称{
}
}
成员内部类
定义
public class Outer {//外部类
public class Inner{//内部类
int size = 0;
public void innerMethod(){
//内部类可以访问外部类的私有方法
System.out.println("这是"+name+"的内部类的方法");
}
}
private String name;
public Outer() {
}
public Outer(String name) {
this.name = name;
}
public void externalMethod(){
System.out.println("这是外部类的方法");
new Inner().innerMethod();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用
用
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
Outer.Inner inner = new Outer().new Inner();
同名变量
区分内部类局部变量、内部类成员变量、外部类成员变量
- 访问外部类成员变量:外部类名.this.外部成员变量名
- 访问内部类成员变量:this.内部类成员变量名
- 访问内部类局部变量:内部类局部变量名
局部内部类
定义在一个方法里的类,只有当前方法才能使用。
修饰符 class 外部类名称{
修饰符 返回值类型 外部方法名(参数列表){
class 局部内部类名称{
}
}
}
定义
局部内部类定义不可使用修饰符
package demo;
public class Outer {//外部类
private String name;
public Outer() {
}
public Outer(String name) {
this.name = name;
}
public void OuterMethod(){
System.out.println("这是外部类的方法");
final String hobbit = "sss";
class Inner{//内部类
int size = 0;
public void innerMethod(){
//内部类可以访问外部类的私有方法
System.out.println("这是"+hobbit+"的内部类的方法");
}
}
new Inner().innerMethod();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 在
JDK8
之前局部内部类使用方法的局部变量必须加上final
关键字保证不可变。 - 在
JDK8
之后可以省略final
关键字,但是要保证局部变量不再变。
匿名内部类
如果类(接口的实现类、父类的子类)只需要使用一次,可以省略类的定义使用匿名内部类
修饰符 class 类名{
修饰符 返回值类型 方法名(参数列表){
接口名或父类名 对象名 = new 接口名或父类名{
@Override
//重写实现方法
};
}
}
定义
public class Test {
public static void main(String[] args) {
USBService usb = new USBService() {
@Override
public void open() {
System.out.println("打开");
}
@Override
public void close() {
System.out.println("关闭");
}
};
usb.open();
usb.close();
}
}
留言