前言
一、接口
用关键字interface:接口
public interface Test {
public void method();
public abstract void method(int a);
}
-
抽象类中的抽象方法不能省略abstract关键字,但是接口中的方法声明可以添加abstract也可以不写
-
接口不能直接使用,必须有对应的实现类
-
引入接口的目的在于隔离实现,使用接口而不是使用具体的类,可以实现在实现接口的多个具体实现类之间进行更换
在Java中不直接支持多继承,因为会出现调用的不确定性,所以Java将多继承机制进行良,在Java中变成了多实 现。一个类只能有一个直系双亲类,一个类可以实现多个接口,一个接口可以继承多个接口
定义一个接口
- 接口没有构造器方法,不能定义静态或者非静态代码块
- 没有属性,只能定义常量
- 可以包含抽象方法,也可以没有抽象方法
- 接口允许多重继承,也允许一个类实现多个接口
- 抽象方法必须在实现类中提供实现
- 可以使用default关键字给抽象方法提供默认实现,有默认实现的方法在实现类中可以重新定义,也可以不重 新定义
接口允许多重继承,一个类在继承另一个类的同时,还可以实现多个接口
声明接口的语法 : 访问修饰符 interface 接口名{ } 一般建议接口名称使用形容词
-
如果定义public接口,则规则和定义public类一致,要求接口名称和文件名称一致
-
外部的接口只能使用public、默认这两个范围限定词;如果定义内部接口则可以使用4大范围限定词
-
接口实际上提供了同一的操作界面(方法),如果是JDK1.8-版本则一个方法也不实现,等待某类或某几个类 去实现它的方法【接口中的所有方法必须是抽象的】。如果使用的是JDK1.8+允许使用default在接口中定义默 认实现,这个实现允许在实现类中重新定义覆盖
-
接口中没有属性,只能定义常量,它提供一些常量,实现它的类可以共享这些常量
-
接口可以给出访问控制符,用public修饰的是公共接口,到处可见;如果定义接口没有范围限定词,则只能在 同包中访问
类实现接口
-
一个类在实现某接口的抽象方法时,必须使用完全相同的方法头public
-
如果一个类实现多接口,用逗号隔开
-
如果一个类实现了声明相同方法的两个接口,则被多个接口共用
-
类在实现接口时可以定义它自己的附加成员,这也是最常见的形式
-
如果一个类不完全实现接口的所有方法,必须把类定义成abstract类型的类,任何继承该类的子类必须实现该 接口
接口的作用 :
- 统一访问
- 解耦 通过接口可以隔离具体实现
- 解耦就是 在使用者 和 实现者 之间没有关系。 无论实现者如何改变实现,对于使用者使用不会变化
接口和抽象类的异同点
- 相同点:都是不断向上抽取而来的
- 不同点: 抽象类需要被继承,而且只能单继承 接口需要被实现,而且可以多实现
- 抽象类中可以定义抽象方法和非抽象方法,子类继承后可以直接使用非抽象方法
- 接口中只能定义抽象方法,必须由子类去实现;JDK1.8+中允许接口中的方法有默认实现,实现类中可以直接 使用默认实现,允许覆盖定义
- 抽象类的继承是is a关系,在定义该体系的基本共性内容
- 接口的实现是like a关系,在定义体系额外功能
- 接口中只能定义常量,而且必须被初始化,抽象类中可以定义属性,允许在声明时直接初始化,也可以不初 始化,同时允许定义常量
接口中的方法必须全部是抽象的(JDK1.8+版本中可以通过default关键字定义方法的默认实现,允许定义静态方 法),抽象类中可以有抽象方法也可以有普通方法
二、内部类
一个类或者接口定义在另外一个类或者接口的内部
内部类特点
-
内部类可以访问其外部类的所有变量和方法
-
外部类不能直接访问内部类的实现细节,可以通过创建内部类对象的方式直接访问,不受限定词的影响
-
内部类比外部类多了private/protected/static三个修饰符,这三个修饰符不能用在外部类上
-
非静态内部类不能拥有静态成员,静态内部类则没有这个限制
内部类提供更好的封装,内部类可以直接访问外部类的私有成员,外部类不能直接访问内部类的成员,匿名内部类适合用于创建仅仅使用一次使用的类
内部类分类:
- 在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一 般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。
内部类实际拥有外部类的一个引用,在构造函数中将外部类的引用传递进来。
非静态内部类
public class A1{
protected class B1{}//静态内部类是protected static class B1{}
}
- 在创建非静态内部类对象时,一定要先创建起相应的外部类对象
- 在任何非静态内部类中,都不能有静态数据、静态方法或者又一个静态内部类
构建内部类对象: 外部类.内部类 in=new 外部类().new 内部类();
静态内部类
静态内部类中,可以有静态数据、静态方法或者又一个静态内部类
public class Test {
static class Test2 {
private static int age = 123;
private String str = "asasda";
static {
System.out.println("abc");
}
public static void method() {
System.out.println("static");
}
public void method01() {
}
}
}
静态内部类中,不能访问外部类的非静态成员,这是由Java语法中【静态方法不能直接访问非静态成员】所限 定
局部内部类
可以将内部类定义在一个方法或者一个代码块内
局部内部类需要先定义后使用,不能是先使用后定义
匿名内部类
匿名内部类就是内部类的简写格式
匿名内部类的前提是必须继承或者实现一个外部类或者接口
- 匿名内部类由于没有名字,所以它没有构造函数
- 如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数
- 不能定义静态成员
匿名内部类的使用限制
- 匿名内部类不能是抽象的
- 匿名内部类不能定义构造器,默认和父类相似的构造器
- JDK1.8-要求给局部内部类、匿名内部类访问的局部变量必须使用nal修饰,从JDK1.8开始这个现实被取消 了,但是默认是nal的(不能修改)