面对对象进阶之接口

接口是什么

Java提供了一个关键字interface,用这个关键字我们可以定义出一个特殊的结构:接口。

示例 复制代码
public interface 接口名{
    //成员变量(常量)
    //成员方法(抽象方法)
}

案例

csharp 复制代码
public class Test {
    public static void main(String[] args) {
        // 目标:认识接口。
        System.out.println(A.SCHOOL_NAME);
        // A a = new A();
    }
}

public interface A {
    // 成员变量(常量)
    String SCHOOL_NAME = "黑马程序员";

    // 成员方法(抽象方法)
    void test();
}

由上案例可知:1.用interface关键字修饰的类,Java默认成员变量是常量(不需要用public static final修饰),默认成员方法是抽象方法(无方法体),不能有代码块({}),不能有构造器。2.接口不能创建对象。

那么可以引入下一知识点:接口是用来被类实现(implement) 的,实现接口的类称为实现类。

示例 复制代码
修饰符 class 实现类名 implements 接口1,接口2,接口3,......{

}

案例

less 复制代码
public interface B {
    void testb1();
    void testb2();
}

public interface C {
    void testc1();
    void testc2();
}

// 实现类
public class D implements B, C{
    @Override
    public void testb1() {

    }

    @Override
    public void testb2() {

    }

    @Override
    public void testc1() {

    }

    @Override
    public void testc2() {

    }
}

public class Test {
    public static void main(String[] args) {
        // 目标:认识接口。
        System.out.println(A.SCHOOL_NAME);

        // A a = new A();

        D d = new D();
        d.testb1();
    }
}

由上可知,一个类可以实现多个接口(子类只能有一个父类),实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。实现类可以在main方法中生成对象,并且生成的对象可以调用该类的方法。

接口的好处

  • 弥补了类单继承的不足,类可以同时实现多个接口。
  • 一个类可以实现多个接口,一个接口也可以被多个类实现。让程序可以面向接口编程,这样既不用关心实现的细节,也可以灵活方便的切换各种实现。(可扩展性:新增功能时无需重构整个系统,例如通过接口定义扩展插件)
示例 复制代码
public class Test {
    public static void main(String[] args) {
        // 目标:搞清楚使用接口的好处。
        Driver s = new A();
        s.drive();
        //解耦合是软件设计中的一种核心策略,它指的是通过技术手段将系统的各个组件之间的依赖关系最小化,使其能够独立开发、修改和运行。
        Driver d = new A();
        d.drive();
        //A、B类中drive方法可不同从而实现用Drive类定义对象,但是对象可实现的方法不同,达到解耦合的目的
        Driver e = new B();
        e.drive();
    }
}

class B implements Driver{
    @Override
    public void drive() {
    
    }
}

class A extends Student implements Driver, Singer{
    @Override
    public void drive() {
    
    }

    @Override
    public void sing() {

    }
}

class Student{

}

interface Driver{
    void drive();
}

interface Singer{
    void sing();
}

JDK8开始,接口新增了三种形式的方法

  1. 默认方法(实例方法):使用用default修饰,默认会被加上public修饰。
  2. 私有方法:必须用private修饰(JDK 9开始才支持)
  3. 类方法(静态方法):使用static修饰,默认会被加上public修饰。
示例 复制代码
public interface A {
    /**
     * 1、默认方法:必须使用default修饰,默认会被public修饰
     * 实例方法:对象的方法,必须使用实现类的对象来访问。
     */
    default void test1(){
        System.out.println("===默认方法==");
        test2();
    }

    /**
     * 2、私有方法:必须使用private修饰。(JDK 9开始才支持的)
     *   实例方法:对象的方法。
     */
    private void test2(){
        System.out.println("===私有方法==");
    }

    /**
     * 3、静态方法:必须使用static修饰,默认会被public修饰
     */
    static void test3(){
        System.out.println("==静态方法==");
    }

    void test4();
    void test5();
    default void test6(){

    }
}

新增方法的好处:增强了接口的能力,更便于项目的扩展和维护。

接口的多继承

简而言之,一个接口可以继承多个接口,便于实现类去实现

示例 复制代码
public interface C extends B , A{

}

注意事项

  1. 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承。
示例 复制代码
interface I{
    void test1();
}
interface J{
    String test1();
}
//interface K extends I, J{//报错
//
//}
  1. 一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现。
示例 复制代码
interface I{
    void test1();
}
interface J{
    String test1();
}
//class E implements I, J{
//
//}
  1. 一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父类的。
typescript 复制代码
public class Test {
   public static void main(String[] args) {
       // 目标:了解使用接口的几点注意事项。
       Zi zi = new Zi();
       zi.run();
   }
}
class Fu{
   public void run(){
       System.out.println("===父类的run方法执行了===");
   }
}
interface IT{
   default void run(){
       System.out.println("===接口IT中的run方法执行了===");
   }
}
class Zi extends Fu implements IT {

}
  1. 一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
csharp 复制代码
interface It1{
    default void test(){
        System.out.println("IT1");
    }
}

interface IT2{
    default void test(){
        System.out.println("IT2");
    }
}

class N implements It1, IT2{
    @Override
    public void test() {
        System.out.println("自己的");
    }
}
相关推荐
Victor35613 小时前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
Victor35614 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术15 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
Gogo81616 小时前
BigInt 与 Number 的爱恨情仇,为何大佬都劝你“能用 Number 就别用 BigInt”?
后端
fuquxiaoguang16 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
毕设源码_廖学姐17 小时前
计算机毕业设计springboot招聘系统网站 基于SpringBoot的在线人才对接平台 SpringBoot驱动的智能求职与招聘服务网
spring boot·后端·课程设计
野犬寒鸦18 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
逍遥德19 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
MX_935920 小时前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
程序员泠零澪回家种桔子20 小时前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构