当前位置: 首页 > news >正文

面向对象高级(5)接口

面向对象高级(5) 接口

接口就是规范,定义的是一组规则,体现了现实世界中“如果是...则必须能...”的思想。继承是一个"是不是"的is-a关系,而接口实现则是 "能不能"的has-a关系。

1、接口的定义格式

接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型

引用数据类型:数组,类,枚举,接口,注解。

修饰符 interface 接口名{
    //接口的成员列表:

//默认方法:

default 返回值类型 方法名(){

}


    // 公共的静态常量

public static final 数据类型 变量名;//提示:前置修饰中public static final可以省略)


    // 公共的抽象方法public abstract可省略;

public abstract 返回值 方法名(){

}
    
    // 公共的默认方法(JDK1.8以上)
    // 公共的静态方法(JDK1.8以上)
    // 私有方法(JDK1.9以上)
}

不能声明构造器、代码块。

2、接口的实现

1类实现接口(implements)

接口不能创建对象,但是可以被类实现(implements ,类似于被继承)。

类与接口的关系为实现关系,即类实现接口实现了接口的类称为实现类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

修饰符 class 实现类的类名  implements 接口{
// 必须:重写接口中的抽象方法如果实现类是抽象类,那么可以不重写
   // 可以:重写接口中的默认方法
}

修饰符 class 实现类 extends 父类 implements 接口{
//必须重写所有的抽象方法
}

注意:

  • 如果接口的实现类是非抽象类,那么必须重写接口中所有抽象方法
  • 默认方法可以选择保留,也可以重写。default不能省略。
  • 重写时,default单词就不要再写了,它只用于在接口中表示默认方法,到实现类中就没有默认方法的概念了
  • 接口中的静态方法不能被继承也不能被重写static不能省略

public interface Ipower {

    void power();//抽象方法

    default void brand(){

        System.out.println("famous.");

    }//默认方法

}

 public class IpowerTest implements Ipower{//实现接口

            public void power(){

            System.out.println("Charge.");

        }//重写抽象方法

    public static void main(String[] args){

        IpowerTest t = new IpowerTest();//创建实例对象

        t.power();//调用重写后的抽象方法

    }

}

(2)接口的多实现

对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。

实现格式:

1.修饰符 class 实现类  implements 接口1,接口2,接口3。。。{
// 重写接口中所有抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写
   // 重写接口中默认方法【可选】
}

2.修饰符 class 实现类 extends 父类 implements 接口1,接口2,接口3。。。{
    // 重写接口中所有抽象方法【必须】,包括父类中的抽象方法与接口中的抽象方法,除非子类也声明为声明为抽象类才可以不重写。
   // 重写接口中默认方法【可选】
}

接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次

定义多个接口:

public interface A {
    void showA();
}

public interface B {
    void showB();
}

定义实现类:

public class C implements A,B {
    @Override
    public void showA() {
        System.out.println("showA");
    }

    @Override
    public void showB() {
        System.out.println("showB");
    }
}

定义测试类:

public class TestC {
    public static void main(String[] args) {
        C c = new C();
        c.showA();
        c.showB();
    }
}

(3)接口的多继承

一个接口能继承另一个或者多个接口,接口的继承也使用 extends 关键字,子接口继承父接口的方法。

子接口的实现类需要将接口中所有的抽象方法都进行重写,重名的抽象方法只需要重写一次。

定义父类接口:

public interface Chargeable {
    void charge();
}

定义子类接口:

public interface UsbC extends Chargeable,USB3 {
    void reverse();
}

定义子接口的实现类:

public class TypeCConverter implements UsbC {
    @Override
    public void reverse() {
        System.out.println("正反面都支持");
    }

    @Override
    public void charge() {
        System.out.println("可充电");
    }
}

4接口与实现类对象构成多态引用

实现类 实现接口,类似于子类继承父类,因此,接口类型的变量与实现类的对象之间,也可以构成多态引用。通过接口类型的变量调用方法,最终执行的是new的实现类对象实现的方法体。

接口名 变量名 = new 实现类对象

public class USBTest {
    public static void main(String[] args) {
        Computer c = new Computer();
        Printer p = new Printer();
        c.transferData(p);//USB usb = new Printer();实际执行打印机重写后的方法。
    }
}

interface USB{
    void start();
    void end();
}

class Computer {
    public void transferData(USB usb){
        System.out.println("Successfully connect.");
        usb.start();
        System.out.println("Transferring date...");
        usb.end();
    }
}//通过引用实例变量usb实现USB接口的调用

class Printer implements USB{
    @Override
    public void start() {
        System.out.println("beginning work");
    }

    @Override
    public void end() {
        System.out.println("end work");
    }
}

此处展示有关匿名对象与匿名实现类的书写:

public class USBTest {
    public static void main(String[] args) {
        Computer c = new Computer();
        Printer p = new Printer();
        c.transferData(p);//USB usb = new Print();实际执行打印机重写后的方法。

        System.out.println();
        c.transferData(new Printer());//创建实现类的匿名对象

        System.out.println();
        USB usb = new USB() {
            @Override
            public void start() {
                System.out.println("beginning work");
            }

            @Override
            public void end() {
                System.out.println("end work");
            }
        };
        c.transferData(usb);//创建匿名实现类的对象

        System.out.println();
        c.transferData(new USB() {
            @Override
            public void start() {
                System.out.println("beginning work");
            }

            @Override
            public void end() {
                System.out.println("end work");
            }
        });//创建匿名实现类的匿名对象
    }
}

5使用接口的静态成员

接口不能直接创建对象,但是可以通过接口名直接调用接口的静态方法和静态常量。

public class TestUSB3 {
    public static void main(String[] args) {
        //通过“接口名.”调用接口的静态方法 (JDK8.0才能开始使用)
        USB3.show();
        //通过“接口名.”直接使用接口的静态常量
        System.out.println(USB3.MAX_SPEED);
    }
}

6、使用接口的非静态方法

接口的非静态方法也只能使用“接口名."进行调用,不能通过实现类的对象进行调用

  • 对于接口的抽象方法、默认方法,只能通过实现类对象才可以调用
    • 接口不能直接创建对象,只能创建实现类的对象

public class TestMobileHDD {
    public static void main(String[] args) {
        //创建实现类对象
        MobileHDD b = new MobileHDD();

        //通过实现类对象调用重写的抽象方法,以及接口的默认方法,如果实现类重写了就执行重写的默认方法,如果没有重写,就执行接口中的默认方法
        b.start();
        b.in();
        b.stop();

        //通过接口名调用接口的静态方法
//        MobileHDD.show();
//        b.show();
        Usb3.show();
    }
}

补充:

(1)类优先原则

当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的抽象方法重名,子类就近选择执行父类的成员方法。

(2)接口冲突

实现类实现了多个接口,而多个接口中存在同名同参的方法时,编译不通过,会报错。此时,必须在实现类中重写同名同参的方法。

(3)解决接口冲突后,若仍然想要调用具体的某个接口中同名同参的方法,则采用 接口名.super.方法名();的写法。

小结;

  • 接口本身不能创建对象,只能创建接口的实现类对象,接口类型的变量可以与实现类对象构成多态引用。
  • 声明接口用interface,接口的成员声明有限制:
    • (1)公共的静态常量
    • (2)公共的抽象方法
    • (3)公共的默认方法(JDK8.0 及以上)
    • (4)公共的静态方法(JDK8.0 及以上)
    • (5)私有方法(JDK9.0 及以上)
  • 类可以实现接口,关键字是implements,而且支持多实现。如果实现类不是抽象类,就必须实现接口中所有的抽象方法。如果实现类既要继承父类又要实现父接口,那么继承(extends)在前,实现(implements)在后。
  • 接口可以继承接口,关键字是extends,而且支持多继承。
  • 接口的默认方法可以选择重写或不重写。如果有冲突问题,另行处理。子类重写父接口的默认方法,要去掉default,子接口重写父接口的默认方法,不要去掉default。
  • 接口的静态方法不能被继承,也不能被重写。接口的静态方法只能通过“接口名.静态方法名”进行调用。

http://www.lryc.cn/news/490642.html

相关文章:

  • uniapp发布android上架应用商店权限
  • Centos Stream 9安装Jenkins-2.485 构建自动化项目步骤
  • 电路模型和电路定理(二)
  • 瑞佑液晶控制芯片RA6807系列介绍 (三)软件代码详解 Part.10(让PNG图片动起来)完结篇
  • Qt常用控件 按钮
  • MySQL学习/复习10视图/用户/权限/语言连接数据库
  • vulfocus在线靶场:tomcat-pass-getshell 弱口令 速通手册
  • c#:winform调用bartender实现打印(学习整理笔记)
  • 牛客题库 21738 牛牛与数组
  • 探索PDFMiner:Python中的PDF解析利器
  • 掌握Go语言中的异常控制:panic、recover和defer的深度解析
  • 云讷科技Kerloud无人飞车专利发布
  • 企业信息化-走进身份管理之搭建篇
  • 实践指南:EdgeOne与HAI的梦幻联动
  • Exploring Prompt Engineering: A Systematic Review with SWOT Analysis
  • ByteBuffer 与 ByteBuf 的对比与优缺点分析
  • js高级06-ajax封装和跨域
  • RabbitMQ3:Java客户端快速入门
  • D 型 GaN HEMT 在功率转换方面的优势
  • Java Web后端项目的特点和组成部分
  • Vue3 + Vite + TS 项目引入 Eslint + Pritter
  • 用Tauri框架构建跨平台桌面应用:1、Tauri快速开始
  • Django实现智能问答助手-数据库方式读取问题和答案
  • stm32利用LED配置基础寄存器+体验滴答定时器+hal库环境配置
  • JAVA开源项目 桂林旅游景点导游平台 计算机毕业设计
  • docker安装使用Elasticsearch,解决启动后无法访问9200问题
  • GM、BP、LSTM时间预测预测代码
  • 《操作系统 - 清华大学》4 -5:非连续内存分配:页表一反向页表
  • 志愿者小程序源码社区网格志愿者服务小程序php
  • Java语言编程,通过阿里云mongo数据库监控实现数据库的连接池优化