接口就是给出一些没有实现的方法封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。语法 :
interface 接口名{
//属性
//方法(1.抽象方法,2.默认实现方法,3.静态方法)
}
class 类名 implements 接口{
自己属性;
自己方法;
必须实现的接口的抽象方法;//添加接口快捷方法ctrl+enter
}
注意事项
(1),在jdk7.0前接口里所有方法都没有方法体,即都是抽象方法
(2),jdk8.0后接口里可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现。
(3),接口不能被实例化,但是可以声明接口变量,接口变量必须引用实现了这个接口的某个特定接口。
(4),接口中的所有方法是public方法,接口中的抽象方法,可以不用abstract修饰
例: void add();
实际上是 abstract void aaa();
(5),一个不同类实现接口,就必须将盖接口所有方法实现。
(6),抽象类实现接口可以不用实现接口方法。
interface IG{
void say();
void hai();
}
/*class Sb implements IG{
public void say(){
System.out.println("sb");
}
}*/
//error 必须实现接口里所有方法
abstract class Sb implements IG{
public void say(){
System.out.println("sb");
}//OK
(7),一个类可以同时可以实现多个接口
nterface IG{
void say();
}
interface GB{
void hai();
}
class Sb **implements IG,GB**{
public void say(){
System.out.println("sb");
}
void hai(){
System.out.println("abc");
}
}
(8),接口中的属性,只能是final,而且是public static final 修饰符。
in a=1;//实际上是public static final int a;必须初始化
(9).接口访问形式:接口名.属性名
IG.sum;
(10).一个接口不能继承其他类,但是可以继承多个其他接口
interdace A entends B,c{}
(11).接口的修饰符只能用public和默认,这点和类的修饰符类似
public interdace A{}
(12).类实现了接口,则可以通过类.接口中的变量名进行调用
interface IG{
int a=2;
}
class B implements IG{
}
在main中
IG.a;
B b=new B();
b.a;
B.a;
都可以完成调用
实现接口VS继承类
(1).解决问题不同
继承:解决代码复用性和可维护性。
接口:设计各种规范方法,让其他类去实现即更加灵活
(2).继承是is-a关系,而接口只需满足like-a
(3).接口在一定程度上实现代码解耦(即 接口规范+动态绑定)
(4). 接口 VS 抽象类,0接口可以提供多重继承的大多好处,同时还能避免多重继承的复杂性和低效性
接口的多态
(1).多参数
IG ig 可以接受多种实现接口类的对象(接口引用可以指向实现接口类的对象)
IG ig=new Sb() ;//接口类型变量可以指向实现接口类的对象实例
类似继承中父类可以指向子类的对象实例
(2).多态数组
IG[] ig=new IG[2] ;
ig[0]=new Sb();
ig[1]=new 实现该接口另外一个类;
instanceof//判断运行类型
语法:ig[i] instanceof Sb
(3).接口多态传递
interface IG{
}
interface GB **extends** IG{
}
class Sb **implements IG**{
}
main中
可以GB gb=new Sb;
默认方法
默认方法的主要优势是提供一种拓展接口的方法,而不破坏现有代码。假如我们有一个已经投入使用接口需要拓展一个新的方法,在JDK8以前,如果为一个使用的接口增加一个新方法,则我们必须在所有实现类中添加该方法的实现,否则编译会出现异常。如果实现类数量少并且我们有权限修改,可能会工作量相对较少。如果实现类比较多或者我们没有权限修改实现类源代码,这样可能就比较麻烦。而默认方法则解决了这个问题,它提供了一个实现,当没有显示提供其他实现时就采用这个实现。这样新添加的方法将不会破坏现有代码。 默认方法的另一个优势是该方法是可选的,子类可以根据不同的需求Override默认实现。
可以为接口提供一个默认实现,必须用default修饰符标记这个方法
public class Outor {
public static void main(String[] args) {
Pig pig=new Pig();
pig.say();
}
}
interface IG{
void say();
default void hai(){//默认方法
System.out.println("默认。。。");
}
}
class Pig implements IG{
@Override
public void say() {
System.out.println("pig。。。");
IG.super.hai();//调用默认方法
}
}
默认方法冲突
如果现在一个接口中将一个方法定义为默认方法,然后再超类或另外一个接口中定义同样的方法,对这种产生二义性问题。
Java遵守的规则:
(1).超类优先
这种情况下只会考虑超类方法,接口的所有默认方法都会忽略。
(2).接口冲突时:
必须由程序员自己确定调用的是哪个方法
例如
IG.super.hai();
此处调用的是IG接口的默认方法。
接口回调
一.产生接口回调的场景 在现实生活中,产生接口回调的场景很简单,比如我主动叫你帮我做一件事,然后你做完这件事之后会通知我,"通知我"这个动作就是接口回调的动作.接口回调重在理解思就好.
public class Outor {
public static void main(String[] args) {
IG ig=new Pig();//
ig.say();//因为接口中没有具体方法,此时就会调用Pig类中的方法
//此时就会产生回调。
}
}
interface IG{
void say();
}
class Pig implements IG{
@Override
public void say() {
System.out.println("pig。。。");
}
}
接口回调更详细请看