目录
在面向对象编程中,接口是一种非常重要的概念,它为类提供了一种统一的行为规范,使得不同的类可以实现相同的接口,从而实现多态和解耦。Java作为一种面向对象的语言,提供了强大的接口支持,使得开发者可以通过接口定义清晰的模块边界,提高代码的可维护性和可扩展性。本文将深入解析Java接口的概念、语法规则、使用场景、特性以及抽象类的区别,并通过实例展示接口的强大功能。
一、接口的概念
在Java中,接口是一种抽象类型,它定义了一组方法的声明(只有方法名、参数和返回值,没有具体实现),但不包含方法的具体逻辑。类可以通过“实现”接口,来继承这些方法声明,并必须在类中具体实现接口里的所有方法。简单来说,接口就像是一份“协议”或者“标准”,规定了某个功能必须包含哪些操作,但不限制具体怎么完成这些操作。例如,我们生活中的USB接口。USB接口本身只是一个标准,它不直接实现“传输数据”或者“充电”的功能。但是U盘、鼠标、充电器等设备,只要“实现”了USB接口的标准(接口的形状匹配、遵循通信协议),就可以插入电脑的USB接口,完成数据传输或充电。就像Java中,类“实现”接口后,必须按照接口要求实现具体方法。
二、接口的语法规则
接口的声明使用关键字interface,其基本语法如下:
public interface 接口名称{
//常量的定义
public static final int a=10; //public static final可以省略不写
// 抽象方法定义
public abstract void method1(); // public abstract 是固定搭配,可以不写
public void method2();
abstract void method3();
void method4();
// 注意:在接口中上述写法都是抽象方法,跟推荐方式4,代码更简洁
}
因此在接口中,变量默认为public static final,即常量,是不能被修改的。接口中的方法默认是public abstract,即抽象方法,没有具体的实现。
三、接口的使用
接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。
如下:
public class 类名称 implements 接口名称{
// ...
}
为便于理解,我将进行代码示例:
先创建USB接口类:
//USB接口
public interface USB {
//定义两个方法表示打开设备和关闭设备
void openDevice();
void closeDevice();
}
创建Mouse类,实现USB接口:
//鼠标类,实现USB接口
public class Mouse implements USB{
//重写接口的方法
@Override
public void closeDevice() {
System.out.println("关闭鼠标....");
}
@Override
public void openDevice() {
System.out.println("打开鼠标....");
}
//定义鼠标自己的方法
public void click(){
System.out.println("鼠标点击...");
}
}
创建Keyboard类,实现USB接口:
//定义键盘类,实现USB接口
public class Keyboard implements USB {
//重写接口的方法
@Override
public void openDevice() {
System.out.println("打开键盘....");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘....");
}
//定义自己的方法
public void input(){
System.out.println("键盘输入...");
}
}
创建Computer类,模拟使用USB设备的电脑:
//笔记本类:使用USB接口
public class Computer {
//定义打开笔记本电脑的方法
public void poweron() {
System.out.println("打开笔记本电脑...");
}
//定义关闭笔记本电脑的方法
public void poweroff() {
System.out.println("关闭笔记本电脑...");
}
//笔记本“使用”USB设备的核心方法,参数是USB类型
// (利用多态,可接收鼠标,键盘等实现类的对象)
public void useDevice(USB usb) {
//第一步打开设备(不管是鼠标还是键盘,都要调用接口的openDevice的方法)
usb.openDevice();
//判断传入的设备是否为鼠标
if (usb instanceof Mouse) { //instanceof是Java类型判断的关键字
//如果是的话,就把usb向下转型为Mouse类型
Mouse mouse = (Mouse) usb;
mouse.click(); //调用鼠标点击功能
}else if (usb instanceof Keyboard){ //如果不是鼠标则要判断是否为键盘
Keyboard keyboard=(Keyboard) usb;
keyboard.input();
}
//最后一步:关闭设备
usb.closeDevice();
}
}
创建Test类:
//测试类
public class Test {
public static void main(String[] args) {
//创建笔记本对象
Computer computer=new Computer();
computer.poweron(); //打开笔记本电脑
System.out.println("==========");
//使用鼠标设备
computer.useDevice(new Mouse());
System.out.println("===========");
//使用键盘设备
computer.useDevice(new Keyboard());
System.out.println("==========");
computer.poweroff(); //关闭笔记本电脑
}
}
测试结果为:
由这段代码可知,接口定义USB设备需要实现的打开和关闭规范。Mouse和Keyboard类实现类的接口,Computer类通过接口统一调用设备通用的操作,结合类型判断调用的特定功能,实现设备灵活扩展与功能调用。这就是接口在面向对象编程里“规范”、“解耦”、“扩展”的实用价值。
四、接口的特性
1. 接口类型是一种引用类型,但是不能直接new接口的对象
接口是引用类型,但不能直接实例化,例如:
运行结果发生了报错:
因此,接口不能被实例化,只能被实现。
2.接口每一个方法都是public的抽象方法,即接口中的方法会被隐式指定为puublic abstract
接口中的方法默认是public abstract,且不能有访问修饰符。
ps:在Java 8以及更高的版本中,接口可以包含默认方法和静态方法。
3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
例如:
代码发生报错
因此接口中的方法不能有方法体,因为接口中的方式默认为抽象方法,只能由实现类提供具体的实现。
4. 重写接口中方法时,不能使用默认的访问权限
例如:
代码发生了报错:
由此可见,在重写接口中的方法时,必须使用public访问修饰符。
5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
接口中的变量默认为 public static final,即常量,不能被修改的。
6. 接口中不能有静态代码块和构造方法
例如:
代码发生了报错。因此,接口中不能有构造方法,因为接口不能被实例化。也不能出现静态代码块,因为接口的职责是“定义规范”而非“承载可执行逻辑”。
7.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
8.如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
例如:
9.jdk8中:接口中还可以包含default方法。
从Java 8开始,接口可以包含默认方法(default 方法)。默认方法提供了一个实现,但子类可以选择重写它。
例如:
//定义USB接口
interface USB{
void open();
void close();
default void display(){
System.out.println("使用了USB接口....");
}
}
//定义实现接口的类Mouse
public class Mouse implements USB {
@Override
public void close() {
System.out.println("关闭鼠标....");
}
@Override
public void open() {
System.out.println("打开鼠标....");
}
}
//测试类
class Test{
public static void main(String[] args) {
Mouse mouse=new Mouse();
mouse.open();
mouse.close();
mouse.display(); //调用接口中的默认方法
}
}
测试结果为:
五、实现多接口
在 Java 中,类和类之间是单继承的,一个类只能有一个父类,即 Java 中不支持多继承 ,但是 一个类可以实现多个接 口。
为了便于理解下面我将通过动物的例子来实现多接口:
我们先定义一个Animal类,它包含了一个基本的属性name和相应的构造函数:
接下来,我们定义几个行为接口,这些接口将被不同的动物类实现,以展示它们的行为特性。
现在,我们将创建几个具体的动物类,这些类将继承自Animal并实现不同的接口组合。
Cat类:
Fish类:
Frog类:
Duck类:
最后我们可以通过一个简单的测试来展示这些动物的行为:
创建Test类:
通过这个示例,我们可以看到Java接口的强大功能,它允许一个类实现多接口,从而具备多种行为。
六、接口间的继承
接口可以继承一个或多个其他接口,形成接口的层次结构。
继承的语法:
interface 子接口 extends 父接口1,父接口2,....{
//可以定义新的方法
}
为了便于理解,下面我将进行代码示例:
定义接口类:实现多重继承
定义Fish类:实现类必须实现的所有方法
Test类:测试
七、抽象类和接口的区别
在上一篇文章中,我们已经对抽象类有了一定的了解啦。到这里我相信大家已经对接口也有了一定的认识,那么抽象类和接口到底有什么不同呢?在Java编程中,抽象类和接口都是用于实现抽象和多态的重要机制,但它们在使用场景和设计理念上有着本质的区别。
在深入讨论区别之前,我们先来看看抽象类和接口的相同点,这有助于我们更好地理解它们地本质:
1.都不能被直接实例化
由此可见,实例化抽象类和接口代码会报错。
2.都可以包含抽象方法
3.都支持多态
//抽象类:
public abstract class Animal {
abstract void eat();
}
//接口Running:
interface Running{
void run();
}
class Dog extends Animal implements Running{
@Override
void eat() {
System.out.println("正在吃东西...");
}
@Override
public void run() {
System.out.println("正在跑...");
}
}
class Test{
public static void main(String[] args) {
//多态的使用
Animal animal=new Dog(); //抽象类的引用
Running running=new Dog(); //接口的引用
}
}
主要区别:
1.成员变量:抽象类可以有示例变量(即非静态变量,而接口中的所有变量默认是public static final的(即常量))。
2.构造函数:抽象类可以有构造函数,接口不能有。
3.方法实现:抽象类可以包含方法的实现。而接口在Java 8之前只能包含抽象方法。从Java 8开始,接口可以包含默认方法和静态方法。
4.多重继承:一个类可以实现多个接口,但只能继承一个抽象类。
5.访问修饰符:抽象类的方法可以有不同的访问修饰符,而接口的方法默认是public的
6.设计目的:抽象类通常用于创建一个基础类,该类可以被其他类继承并扩展。接口则用于定义类必须实现的契约
为便于理解,下面我将进行代码示例:
我定义了一个抽象类Animal和一个接口Bark,并创建了一个Dog类来实现这些抽象和接口的方法
//定义抽象类Animal
public abstract class Animal {
private String name;
//构造方法
public Animal(String name){
this.name=name;
}
public abstract void eat(); //抽象方法
//具体方法
void Move(){
System.out.println(this.name+"正在移动....");
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
}
//定义接口Bark
interface Bark{
void bark(); //抽象方法
}
//定义一个Dog类用于继承抽象类以及接口
class Dog extends Animal implements Bark {
public Dog(String name) {
super(name);
}
@Override
public void eat() {
System.out.println("正在吃东西...");
}
@Override
public void bark() {
System.out.println("正在叫....");
}
}
//Test类:
class Test{
public static void main(String[] args) {
Dog dog=new Dog("旺财");
dog.eat();
dog.bark();
dog.Move();
}
}
测试结果为:
在这个示例中:
抽象类Animal提供了一些通用行为(如 move()方法),并定义了一个抽象方法eat(),要求所有子类必须实现。
接口Bark定义了一个抽象方法bark(),表示能够叫的动物。
实现类Dog继承了Animal抽象类并实现了Bark接口,提供了所有的抽象方法的具体实现。
通过这个示例,我们可以看到抽象类和接口的定义和使用上的区别:
1.抽象类可以包含具体的实现方法,而接口只能包含抽象方法(在Java 8之前)。
2.一个类只能继承一个抽象类,但可以实现多个接口。
3.抽象类通常用于表示"是一个"(is-a)的关系,而接口用于表示”能做“(can-do)的关系
总结:
以上便是Java接口知识要点的梳理,希望这些内容能助力您学习Java接口。感谢您的阅读!若您对Java接口还有疑问,欢迎到评论区交流探讨,祝您在Java学习之旅中收获满满、不断进步!