JDK7及以前,接口中只能定义全局常量和抽象方法
全局常量:用public static final修饰,但是书写时可以省略不写
抽象方法:用public abstract修饰,但是书写时可以省略不写
JDK8,除了定义全局常量和抽象方法以外,还可以定义静态方法和默认方法(用default进行修饰),在接口中可以有方法体了
且可以省略掉修饰静态方法和默认方法的public,这个时候是省略,而不是说权限变成了默认权限,仍然是public权限
静态方法可以直接通过接口来调,对于默认方法,就只能通过接口的实现类来进行调用,对于实现类的对象来说相当于是普通的非静态的方法
public interface CompareA {
public static void method1(){
System.out.println("CompareA:北京");
}
public default void method2(){
System.out.println("CompareA,上海");
}
default void method3(){
System.out.println("CompareA,上海");
}
}
重写默认方法之前
class SubClass implements CompareA{
//刚得到这个结构的时候,不会报错,因为CompareA接口中的方法都是有方法体的,不需要去实现
}
重写默认方法之后:
class SubClass implements CompareA{
public void method2(){//不要用default修饰,否则报错
System.out.println("上海");
}
}
测试;
public class FieldTest {
public static void main(String[] args) {
SubClass s=new SubClass();
//s.method1();报错,说接口中没有定义method1这个方法
//接口中的静态方法实现类是拿不到的,只能通过接口来进行调用,接口中定义的静态方法是想自己用的,相当于充当工具类的角色
//SubClass.method1();报错,说接口中没有定义method1这个方法
CompareA.method1();//CompareA:北京
//通过实现类的对象可以调用接口中的默认方法
s.method2();//CompareA,上海
s.method3();//CompareA,上海
//不能这么做SubClass.method2();
//我们可以去重写默认方法
//重写默认方法method2()之后
//如果实现类重写了接口中的默认方法,调用时,调用的仍然是重写之后的方法
s.method2();//上海
s.method3();//CompareA,上海
}
}
class SubClass implements CompareA{
//刚得到这个结构的时候,不会报错,因为CompareA接口中的方法都是有方法体的,不需要去实现
public void method2(){//不要用default,否则报错
System.out.println("上海");
}
}
测试2:创建SubClass的一个父类SuperClass
public class SuperClass {
public void method3(){//和接口中的method3相比就是没有default进行修饰
System.out.println("SuperClass :北京");
}
}
public class FieldTest {
public static void main(String[] args) {
SubClass s=new SubClass();
s.method2();//上海
//如果类继承的父类或者实现的接口中声明了同名同参数的方法,子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数方法。这个叫做类优先原则(仅仅针对方法而言)
//如果进行了重写,则调用的是重写的方法
s.method3();//SuperClass:北京
}
}
class SubClass extends SuperClass implements CompareA{
//刚得到这个结构的时候,不会报错,因为CompareA接口中的方法都是有方法体的,不需要去实现
public void method2(){//不要用default,否则报错
System.out.println("上海");
}
}
测试3
再创造一个CompareB接口,也有method3方法
public interface CompareB {
default void method3(){
System.out.println("CompareB,上海");
}
}
让类去实现CompareB,
class SubClass extends SuperClass implements CompareA, CompareB{
//刚得到这个结构的时候,不会报错,因为CompareA接口中的方法都是有方法体的,不需要去实现
public void method2(){//不要用default,否则报错
System.out.println("上海");
}
}
s.method3();//SuperClass:北京
不管类实现了多少个接口,在这个类没有重写方法的情况下以父类为准
但如果改成这样呢?如果都是抽象方法,那可以,一起实现就行了,重写一个相当于共同实现了
但现在并没有重写method3,且方法体还不一样,所以会报错
即如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,在实现类没有重写此方法的情况下会报错,这种错误成为接口冲突(如果仍继承SuperClass是不会存在冲突的)
class SubClass implements CompareA, CompareB{
//刚得到这个结构的时候,不会报错,因为CompareA接口中的方法都是有方法体的,不需要去实现
public void method2(){//不要用default,否则报错
System.out.println("上海");
}
}
解决方法,必须在实现类中重写此方法,重写完之后就不报错了,再调用method3就是调用自己重写的方法了
class SubClass implements CompareA, CompareB{
//刚得到这个结构的时候,不会报错,因为CompareA接口中的方法都是有方法体的,不需要去实现
public void method2(){//不要用default,否则报错
System.out.println("上海");
}
public void method3(){
System.out.println("杭州");
}
}
注意:父类中的方法子类可以去重写,再去调,调用的就是子类中的方法,但如果在子类的代码中有需求就是想去调用父类的方法,可以用super
class SubClass extends SuperClass implements CompareA, CompareB{
//刚得到这个结构的时候,不会报错,因为CompareA接口中的方法都是有方法体的,不需要去实现
public void method2(){//不要用default,否则报错
System.out.println("上海");
}
public void method3(){
System.out.println("杭州");
}
public void test(){
method3();//自己定义的重写方法
super.method3();//调用父类中的method3方法
//接口名.的方式只能去调用接口中的静态方法
CompareA.super.method3();//调用接口中的默认方法
CompareB.super.method3();//调用接口中的默认方法
}
}