java的接口

接口

定义

接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似。没有构造方法,不能创建对象.只能定义:公开静态常量、公开抽象方法

特点

  1. 使用interface关键字定义接口
    • interface 接口名{}
    • 接口中abstract关键字可以省略
  2. 类实现接口使用implements表示
    • class 类名 implements 接口名 {}
  3. 接口不能实例化
    • 接口按照多态的形式实例化
  4. 接口的子类
    • 可以是接口,使用extends继承
    • 可以是抽象类,但是意义不大
    • 可以是实体类,需要重写接口中所有的抽象方法(使用最多)
  5. 接口中的成员变量必须是静态的、最终、公共的,也就是常量
    • public、static、final关键字可以省略
public interface MyInterface {
    //公开的静态常量
    String num = "vadv";
    //公开的抽象方法
    void method();
}

通过implements实现接口,并且重写所以接口中的方法

public class TestInterface {
    public static void main(String[] args) {
        //接口 变量=new 实现接口的类
        MyInterface myInterface = new Impl();
        //调用方法
        myInterface.method();
    }
}

class Impl implements MyInterface {
//覆盖接口method方法
    @Override
    public void method() {
        System.out.println("实现接口");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dgfrB8Qh-1645535351940)(F:\笔记文件\JavaSE\10、接口\接口.assets\image-20210921012121319.png)]

//接⼝1
public interface MyInterface {
    //定义了静态常量 static final 可以省略
    static final String NAME = "⼩红";
    //定义了抽象⽅法
    public void method();
    //定义了抽象⽅法
    public void method2();
}
//接⼝2 继承了接⼝1
public interface MyInterface2 extends MyInterface {
    //定义了抽象⽅法
    public void method2();
}
//定义实现类实现接⼝
public class MyInterfaceSon implements MyInterface2{
    //重写抽象⽅法
    @Override
    public void method() {
    	System.out.println("重写method抽象⽅法");
    }
    //重写抽象⽅法
    @Override
    public void method2() {
    	System.out.println("重写method2抽象⽅法");
    }
}

好处

  • 降低程序的耦合度
  • 更自然的使用多态
  • 设计和实现完全分离
  • 更加容易搭建程序框架
  • 更加容易更换具体实现

接口与类的异同

类与类

  • 继承关系只能单继承,不能多继承,但是可以多层继承
  • 多继承:子类继承父类,父类继承祖父类
  • 如果多个父类出现相同的方法,无法区分

类与接口

  • 实现关系可以单实现,也可以多实现,在继承的同时可以多实现
  • 多个接口出现了名称、参数列表相同的方法,但是返回值不同,会报错

接口与接口

  • 继承关系,可以单继承,也可以多继承
  • 如果多个父类出现了相同的,子类用谁都可以

接口与抽象类

相同:

  • 可编译成字节码文件。
  • ​ 不能创建对象。
  • ​ 可以作为引用类型。
  • ​ 具备Object类中所定义的方法。

不同:

  • 所有属性都是公开静态常量,隐式使用public static final修饰。
  • 所有方法都是公开抽象方法,隐式使用public abstract修饰。
  • 没有构造方法、动态代码块、静态代码块。
  • 一个类只能继承一个抽象类,但是一个类可以实现多个接口
  • 抽象类有实例变量,接口只有类变量

为解决多继承关系,Java8提供了下⾯三条规则:

  • 类中的⽅法优先级最⾼,类或⽗类中声明的⽅法的优先级⾼于任何声明为默认⽅法的优先
    级。
  • 如果第⼀条⽆法判断,那么⼦接⼝的优先级更⾼:⽅法名相同时,优先选择拥有最具体实现的默认⽅法的接⼝, 即如果B继承了A,那么B就⽐A更加具体。
  • 如果还是⽆法判断,继承了多个接⼝的类必须通过显式覆盖和调⽤期望的⽅法, 显式地选择使⽤哪⼀个默认⽅法的实现。
public interface A {
    default void hello() {
	System.out.println("hello from A");
	}
}
public interface B extends A {
    default void hello() {
    	System.out.println("hello from B");
    }
}
public class C implements A, B {
    public static void main(String[] args) {
    	new C().hello();
    }
}

因为B继承了A,所以B⽐A更具体,所以应该选择B的hello()⽅法。所以,程序会打印输
出"hello from B"。

public interface A {
    default void hello() {
    	System.out.println("hello from A");
    }
}
public interface B extends A {
    default void hello() {
    	System.out.println("hello from B");
    }
}
public class D implements A {
}
public class C extends D implements A, B {
    public static void main(String[] args) {
    	new C().hello();
    }
}

C虽然继承了D,但D中未覆盖A的默认⽅法,接着,编译器会在A和B中做选择,由于B更具体,所以,程序会打印输出"hello from B"。

public interface A {
    default void hello() {
    	System.out.println("hello from A");
    }
}
public interface B extends A {
    default void hello() {
    	System.out.println("hello from B");
    }
}
public class D implements A {
    public void hello() {
    	System.out.println("hello from D");
    }
}
public class C extends D implements A, B {
    public static void main(String[] args) {
    	new C().hello();
    }
}

⽗类中声明的⽅法具有更⾼的优先级,所以程序会打印输出"hello from D"。

public interface A {
    default void hello() {
    	System.out.println("hello from A");
    }
}
public interface B {
    default void hello() {
    	System.out.println("hello from B");
    }
}
public class C extends D implements A, B {
    public static void main(String[] args) {
    	new C().hello();
    }
}

由于编译器⽆法识别A还是B的实现更加具体,所以会抛出编译错误:”C inherits unrelateddefaults for hello() from types A and B“。

像这种场景要解决冲突,可以在C中覆盖hello()⽅法并在⽅法内显示的选择调⽤A还是B的⽅法。

public class C extends D implements A, B {
    public void hello() {
        // 显式地选择调⽤接⼝B中的⽅法
        // 同理,要调⽤接⼝A中的⽅法,可以这样:A.super.hello()
        B.super.hello();
}
    public static void main(String[] args) {
        // 输出 hello from B
        new C().hello();
    }
}
public interface A {
    default void hello() {
        System.out.println("hello from A");
    }
}
public interface B extends A{
}
public interface C extends A{
}
public class D implements B, C {
    public void hello() {
    	new D().hello();
    }
}

只有⼀个⽅法申明可以选择,所以程序会输出"hello from A"。

默认方法

在1.8以后,接口中存在默认的方法

public interface Sized {
    // 普通抽象⽅法,默认是public abstract修饰的,没有⽅法体
    int size();
    /*
    * 默认⽅法,有⽅法体
    * 任何⼀个实现了Sized接⼝的类都会向动继承isEmpty的实现
    */
    default boolean isEmpty() {
    return this.size() == 0;
    }
}

应用

//飞翔接口
public interface MyInterface {
 void fly();
}

public class TestInterface {
    public static void main(String[] args) {
        Impl impl = new Impl("jack");
        impl.fly();
        System.out.println("*****使用多态********");
        MyInterface myInterface = new Impl("mkie");
        myInterface.fly();
    }
}

class Impl implements MyInterface {
    String name;
    //带参构造方法
    public Impl(String name) {
        this.name = name;
    }

    //覆盖原来fly方法,实现方法体
    @Override
    public void fly() {
        System.out.println(name + "在飞翔");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NTWxOz2e-1645535351942)(F:\笔记文件\JavaSE\10、接口\接口.assets\image-20210921090759851.png)]

规范

  • 任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
  • 实现接口中的抽象方法时,访问修饰符必须是public。

引用

  • 同父类一样,接口也可声明为引用,并指向实现类对象。interface 对象名 = new 实现类()
  • 仅可调用接口中所声明的方法,不可调用实现类中独有的方法。
  • 可强转回实现类本身类型,进行独有方法调用。
  • 特殊:通过接口可调用0bject中的公开方法]

接口的多态

//飞翔接口
interface MyInterface {
    void fly();
}

//父类:抽象类
abstract class Animal {
    public void eat() {
        System.out.println("吃......");
    }
}

//子类继承父类,并且时间接口
class Dog extends Animal implements MyInterface {

    @Override
    public void fly() {
        System.out.println("飞翔....");
    }
    //子类特有方法
    public void run() {
        System.out.println("跑.....");
    }
}

class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.run();
        System.out.println("****以下是多态****");
        Animal animal = new Dog();
        animal.eat();
        MyInterface myInterface = new Dog();
        myInterface.fly();
    }
}

常见关系

  1. 类与类
    • 单继承 extends 父类名称
  2. 类与接口
    • ​ 多实现 implements 接口名称1,接口名称2,接口名称n
  3. 接口与接口:
    • 多继承 extends父接口1,父接口2,父接口n

常量接口、标记接口

常量接口将多个常用于表示状态或固定值的变量,以静态常量的形式定义在接口中统一管理;提高代码可读性。

//常量接口
public interface ConstInterface {
   String CONST="AAA";
}
class TestConstInterface{
    public static void main(String[] args) {
        if (ConstInterface.CONST.equals("AAA")){
            System.out.println(ConstInterface.CONST);
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JdIp9WyD-1645535351942)(F:\笔记文件\JavaSE\10、接口\接口.assets\image-20210921093658501.png)]

标记接口中没有包含任意成员,仅仅用作标记。
Serializable:序列化
Cloneable:克隆

接口回调

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIgdijLQ-1645535351943)(F:\笔记文件\JavaSE\10、接口\接口.assets\20210813165040879_28759.png)]

class TestUsb {
    public static void main(String[] args) {
        //实例化
        Computer computer = new Computer();
        Usb mouse = new Mouse();
        Usb fan = new Fan();
        Usb Upan = new Upan();
        //将usb1、2、3赋值,在run方法在判断,只要不为空,就会根据数据类型调用service()
        computer.usb1 = Upan;
        computer.usb2 = fan;
        computer.usb3 = mouse;
        computer.run();

    }
}

public interface Usb {
    void service();
}

class Upan implements Usb {
    @Override
    public void service() {
        System.out.println("U盘连接电脑成功,开始工作。。。");
    }
}

class Fan implements Usb {
    @Override
    public void service() {
        System.out.println("风扇连接电脑成功,开始工作。。。");
    }
}

class Mouse implements Usb {
    @Override
    public void service() {
        System.out.println("鼠标连接电脑成功,开始工作。。。");
    }
}

class Computer {
    Usb usb1;
    Usb usb2;
    Usb usb3;

    public void run() {
        System.out.println("电脑开始工作......");
        if (usb1 != null) {
            usb1.service();
        }
        if (usb2 != null) {
            usb2.service();
        }
        if (usb3 != null) {
            usb3.service();
        }
    }
}

总结

什么是接口

微观:接口是一种能力和约定。
宏观;接口是一种标准。

接口与类的异同

没有构避方法,仅可定义公开静态常量与公开抽象方法。

接口的应用

Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。

接口的规范

任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
实现接口中的抽象方法时,访问修饰符必须是public。

什么是常量接口

将多个常用于表示状态或固定值的变量,以静态常量的形式定义在接口中统一管理。

什么是接口回调

先有接口的使用者,后有接口的实现者。

接口的好处

程序的耦合度降低。
更自然的使用多态。
设计与实现完全分离。
更容易搭建程序框架。

93800797.png" alt="image-20210921093800797" style="zoom:67%;" />

总结

什么是接口

微观:接口是一种能力和约定。
宏观;接口是一种标准。

接口与类的异同

没有构避方法,仅可定义公开静态常量与公开抽象方法。

接口的应用

Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。

接口的规范

任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
实现接口中的抽象方法时,访问修饰符必须是public。

什么是常量接口

将多个常用于表示状态或固定值的变量,以静态常量的形式定义在接口中统一管理。

什么是接口回调

先有接口的使用者,后有接口的实现者。

接口的好处

程序的耦合度降低。
更自然的使用多态。
设计与实现完全分离。
更容易搭建程序框架。
更容易更换具体实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值