java interface(java接口)

接口的特点

注意只针对JDK8之前的

  1. 接口中的方法可以有参数列表和返回类型, 所有方法都没有方法体。

  2. 接口没有构造方法。因为构造方法用于创建对象。

  3. 接口中所有 成员变量都默认是由 public static final 修饰的。

  4. 接口中的字段只是被存储在该接口的静态存储区域内,而不属于该接口。

  5. 接口中的方法可以被声明为 public 或不声明,但结果都会按照 public 类型处理。

  6. 接口中的 所有方法都默认是由 public abstract 修饰的。也可以使用 protected ,但不能用 private 。

  7. 当实现一个接口时,需要将被定义的方法声明为 public 类型的,否则为默认访问类型, Java 编译器不允许这种情况。

  8. 如果没有实现接口中所有方法,那么创建的仍然是一个接口。

  9. 扩展一个接口来生成新的接口应使用关键字 extends ,实现一个接口使用 implements 。

  10. 一个接口同时继承多个接口 (interface C extends A, B {}是可以的.)

  11. 接口中的方法是抽象方法(abstract),不能是静态方法(static).接口的所有方法都是抽象的,而抽象方法是没有static,有static的方法是不能override的,所以这样定义接口才有意义。

  12. 实现接口的类 必须提供接口中所有方法的具体实现内容。

Java(JDK)8接口

JDK8版本,接口中允许有以下三种方法:

  • abstract修饰的抽象方法:public abstract 返回类型 方法名(参数);
  • default修饰的默认方法:public default 返回类型 方法名(参数) {方法体};
  • static修饰的静态方法:public static 返回类型 方法名(参数) {方法体};

Java(JDK)8接口新特性

  1. 接口中可以使用 default 关键字修饰的非抽象方法。即:默认方法(或扩展方法),实现类可重写或不重写,
  2. 接口里可以使用static关键字修饰接口的静态方法,实现类和子接口不可以重写接口静态方法,接口中定义的静态方法,只能通过接口来调用。

Java(JDK)8接口规则

public interface CompareA {
    
    
    //静态方法
    public static void method1(){
    
    
        System.out.println("CompareA:北京");
    }

    //默认方法
    public default void method2(){
    
    
        System.out.println("CompareA:上海");
    }
    
    public default void method3(){
    
    
        System.out.println("CompareA");
    }
}
  1. 接口中定义的静态方法,只能通过接口来调用
    public class SubClassTest {
          
          
        public static void main(String[] args) {
          
          
            SubClass s = new SubClass();
            //s.method1();  错误写法
            CompareA.method1();
        }
    }
    
    class SubClass implements CompareA{
          
          
    	
    }
    
  2. 通过实现类的对象,可以调用接口中的默认方法。
  3. 如果实现类重写了接口中的默认方法,调用时仍然调用的是重写以后的方法。

子接口和父接口的方法重写

接口静态方法是不能被实现类和子接口实现的

​ 接口静态方法是不能被实现类和子接口重写

default(默认)方法是可以被实现类和子接口实现的

​ 子接口继承父接口重写父接口的默认方法。

代码示例如下:

interface interfaceA{
    
    
     default void defaultMethod(){
    
    
        System.out.println("interfaceA defaultMethod 方法");
    }
}

interface interfaceB extends interfaceA{
    
    
    default void defaultMethod(){
    
    
        //通过接口名.super.方法名来调用父类
        interfaceA.super.defaultMethod();
        System.out.println("interfaceB defaultMethod 方法");
    }
}
interface interfaceC extends interfaceB{
    
    
    default void defaultMethod(){
    
    
        interfaceA.super.defaultMethod();
        interfaceB.super.defaultMethod();
        System.out.println("interfaceB defaultMethod 方法");
    }
}

​ 如果每个重写方法都调用其超级方法,则您会有一系列调用。一般情况,一个实现可以始终覆盖默认方法而无需调用super

接口中同名变量和方法

注意当前目录下是针对JDK8之前的。

1.父类与接口或接口之间出现同名变量

注意 接口中的同名变量属于常量( public static final 修饰),只能用接口名.常量名调用。

问题一: 在实现接口和继承父类都存在相同变量时,导致子类无法抉择。
解决方法:

​ 在子类的方法中显示表明要输出的变量是父类还是接口的变量。(super/接口名.变量名)。

代码示例如下:
interface interfaceA{
    
    
    int value = 0;
}
class ClassA{
    
    
    int value=10;
}
interface interface2{
    
    
    int value = 100;
}
class Test extends ClassA implements interfaceA,interface2{
    
    
    public int getValue(){
    
    
        //return super.value;	//父类中的i
        //return A.value;		//接口A中的i
        return A2.value;		//接口A2中的i
    }
}
public class TestMain {
    
    
    public static void main(String[] args) {
    
    
        Test t = new Test();
        System.out.println(t.printI());
    }
}

2.父类与接口中存在同名方法

代码示例如下:
interface interfaceA{
    
    
    public void methodA();
}
class ClassA{
    
    
     public void methodA(){
    
    
         System.out.println("ClassA中的methodA()方法");
     };
}

class Test extends ClassA implements interfaceA{
    
    
   	//注意:这里子类不重写接口的方法,也不会报错
    //子类直接继承父类和实现接口不实现接口方法不报错,说明这种情况下默认父类实现该方法
}
public class TestMain {
    
    
    public static void main(String[] args) {
    
    
        Test t = new Test();
       	t.methodA();
    }
}
//打印日志
//我是Test类中的methodA()方法
  • 若子类没有重写方法,则默认会优先调用父类中的方法,不会报错。

    注意:这里父类已经有了接口中的方法,不重写接口的方法,也不会报错
    子类直接继承父类和实现接口不实现接口方法不报错,说明这种情况下默认父类实现该方法

  • 若子类重写了该方法,则相当于同时重写了父类以及接口中的方法。注意:调用的是子类重写后的方法。

class Test extends ClassA implements interfaceA{
    
    
   	 @Override
    public void methodA() {
    
    
        System.out.println("Test中的methodA()方法");
    }
    
}
public static void main(String[] args) {
    
    
        Test t = new Test();
       	t.methodA();
    }
//打印日志
//Test中的methodA()方法
  • 若子类想用父类的方法,可以通过super.方法名
class Test extends ClassA implements interfaceA{
    
    
   	 @Override
    public void methodA() {
    
    
        super.methodA()
        System.out.println("Test中的methodA()方法");
    }
    
}
public static void main(String[] args) {
    
    
        Test t = new Test();
       	t.methodA();
    }
//打印日志
//ClassA中的methodA()方法
//Test中的methodA()方法

3.接口和接口之间存在同名方法

1.参数列表+返回值 都相同:实现类只要实现一次此方法即可
interface interfaceA{
    
    
    public void methodA();
}
interface interface2{
    
    
    public void methodA();

}
class Test implements interfaceA,interface2{
    
    
   	 @Override
     public void methodA(){
    
    
         System.out.println("Test中的methodA()方法");
     };
}
public class TestMain {
    
    
    public static void main(String[] args) {
    
    
        Test t = new Test();
        t.methodA();
    }
}
//打印日志
//Test中的methodA()方法
2.参数列表相同+返回值不同:实现类无法直接实现两个方法(IDE报错)。
interface interfaceA{
    
    
    public void methodA();
}
interface interface2{
    
    
    public int methodA();

}
class Test implements interfaceA,interface2{
    
    
    //编译期就会直接报错
   	//英文:'methodA()' in 'Test' clashes with 'methodA()' in 'InterfaceB';
    //attempting to use incompatible return type
   	//中文:'Test' 中的 'methodA()' 与 'InterfaceB' 中的 'methodA()' 冲突;
    //尝试使用不兼容的返回类型
    //无论重写哪一个接口中的方法都会报错,返回参数不同,定位不到哪个方法。
     @Override
     public void methodA(){
    
    
     };
}
3.参数列表不相同:实现类可以分别实现两个方法
interface interfaceA{
    
    
    public void methodA();
}
interface interfaceB{
    
    
    public int methodA(String name);

}
class Test implements interfaceA,interfaceB{
    
    
 	//参数列表不相同,分别重写,构成Test类重载。
     @Override
     public void methodA(){
    
    
         System.out.println("Test中的methodA()方法");
     }
     @Override
     public void methodA(String name){
    
    
         System.out.println("Test中的methodA(value="+name+")方法");
     };
}
public class TestMain {
    
    
    public static void main(String[] args) {
    
    
        Test t = new Test();
		t.methodA();
       	t.methodA("fry");

    }
}
//打印日志
//Test中的methodA()方法
//Test中的methodA(value=fry)方法

猜你喜欢

转载自blog.csdn.net/fry3309/article/details/124440331