❤️❤️前言~🥳🎉🎉🎉
hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥💥,如果发现这篇文章有问题的话,欢迎各位评论留言指正,大家一起加油!一起chin up!👍👍
💥个人主页:E绵绵的博客
💥 所属专栏:JAVASE题目练习 JAVASE知识点专栏 c语言知识点专栏 c语言题目练习
那现在我们就开始接口的学习吧。(接口这部分作者打算两篇文章介绍完)
接口的概念
接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。
在Java中,接口可以看成是:多个类的公共规范,它是一种引用数据类型。
接口的语法规则
接口的定义格式与定义类的格式基本相同,将class关键字换成interface 关键字,就定义了一个接口。
public interface 接口名称{
// 抽象方法
public abstract void method1(); // public abstract 是固定搭配,可以不写
public void method2();
abstract void method3();
void method4();
// 注意:在接口中上述写法都是抽象方法,更推荐方式4,代码更简洁
}
❤️❤️提示:
1. 创建接口时, 接口的命名一般以大写字母开头.
2. 阿里编码规范中约定, 接口中的方法和属性一般不要加任何修饰符号(除default,static), 保持代码的简洁性.
接口的使用
💥💥接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。
注意:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。
// USB接口
public interface USB {
void openDevice();
void closeDevice();
}
// 鼠标类,实现USB接口
public class Mouse implements USB {
@Override
public void openDevice() {
System.out.println("打开鼠标");
}
@Override
public void closeDevice() {
System.out.println("关闭鼠标");
}
public void click(){
System.out.println("鼠标点击");
}
}
// 键盘类,实现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("键盘输入");
}
}
// 笔记本类:使用USB设备
public class Computer {
public void powerOn(){
System.out.println("打开笔记本电脑");
}
public void powerOff(){
System.out.println("关闭笔记本电脑");
}
public void useDevice(USB usb){
usb.openDevice();
if(usb instanceof Mouse){
Mouse mouse = (Mouse)usb;
mouse.click();
}else if(usb instanceof KeyBoard){
KeyBoard keyBoard = (KeyBoard)usb;
keyBoard.inPut();
}
usb.closeDevice();
}
}
// 测试类:
public class TestUSB {
public static void main(String[] args) {
Computer computer = new Computer();
computer.powerOn();
// 使用鼠标设备
computer.useDevice(new Mouse());
// 使用键盘设备
computer.useDevice(new KeyBoard());
computer.powerOff();
}
}
🎯🎯接口特性
❤️❤️1. 接口类型是一种引用类型,但是不能直接用它创建接口的实例对象,只能当作引用变量去接收跟其有(implements)实现关系的类的实例对象。
public class TestUSB { public static void main(String[] args) { USB usb = new USB(); } } // Error:(10, 19) java: day20210915.USB是抽象的; 无法实例化
❤️❤️2.接口中的成员变量类型都必须是 public static final ,如果我们不写 public static final或者缺一部分它都依然代表public static final。
但切记如果其中出现了不同的修饰词,那就会报错,如protected static 这种直接报错,因为出现了不同的修饰词(缺少一部分都不要紧,就是不能出现不同的修饰词)
public interface USB { double brand = 3.0; // 默认被:final public static修饰 void openDevice(); void closeDevice(); } public class TestUSB { public static void main(String[] args) { System.out.println(USB.brand); // 可以直接通过接口名访问,说明是静态的 // 编译报错:Error:(12, 12) java: 无法为最终变量brand分配值 USB.brand = 2.0; // 说明brand具有final属性 } }
❤️❤️🎯🎯 (重点)3.接口当中的方法分为三种: 抽象方法,static修饰的方法,default修饰的方法
1.抽象方法必须是public abstract类型,其道理跟接口的成员变量一样,都是能缺块,甚至不写,但不能出现不同。
其抽象方法不能被直接实现(需要重写去间接实现),而接下来的下面两种方法都是能被直接实现的。
interface USB { // Error:(4, 18) java: 此处不允许使用修饰符private private void openDevice(); void closeDevice(); }
2.接口中static修饰的方法类型必须为public static ,可以隐藏变为static。其不能被重写。它的使用方式跟平常所见的static修饰方法没区别
3.用defalut修饰的类型同理必须为public defalut,可以隐藏变为defalut。对于该方法,可以不重写,也可以重写。我们可以认为它跟普通类中的非静态方法一样,使用也是跟非静态方法差不多的。
❤️❤️4.重写接口中方法时,访问修饰符必须为public
public interface USB { public class Mouse implements USB { @Override void openDevice() { System.out.println("打开鼠标"); } // ... } // 编译报错,重写USB中openDevice方法时,不能使用默认修饰符 // 正在尝试分配更低的访问权限; 以前为public
❤️❤️5.接口中不能有静态代码块,实例代码块,构造方法出现,否则会报错
public interface USB { // 编译失败 public USB(){ } {} // 编译失败 void openDevice(); void closeDevice(); }
❤️❤️🎯🎯 (重点)6. 接口中的成员访问修饰符想必大家都清楚,都是默认且必须用public访问修饰符修饰。而到了我们的接口,其不需要用访问修饰符修饰,默认就是public修饰符,但如果你用访问修饰符修饰,它则会报错。
而对于接口我们还要清楚它是用abstract修饰的,所以内部才会有抽象方法。我们平常没见到abstract修饰接口,是因为即使不主动用abstract修饰接口,系统也会默认用abstarct隐藏修饰它,所以不写sbstract也可以。
❤️❤️7 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class,也是有对应的字节码文件。(所以我们其实可以把接口认为是一个特殊的类)
❤️❤️8. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类。
🎯🎯实现多个接口//继承和接口并用
💕💕 在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承,但是我们的一个类可以实现多个接口。
而且一个类还可以在继承父类的同时实施多个接口。
注意继承和接口并用的话,extends必须在implements前面,否则会报错。
🎯🎯 对于继承和接口并用时的子类内存分布如下,以下图为例。
下图代码能证明内存分布跟我们上图中的一样
正是因为都独立存在于子类中,所以在子类的实例对象中中找a变量才不明确,不确定为哪个。
接口间的继承
❤️❤️在接口中,继承是指一个接口可以继承一个接口或多个接口(注意可以继承多个接口)。接口中的继承可以通过关键字"extends"来实现,通过继承父接口可以拥有父接口的方法和属性,并且可以在子接口中添加新的方法和属性。子接口可以使用继承的方法和属性。
对于接口继承后的使用,是跟普通类继承的使用一样。
继承的好处是可以实现代码的重用和模块化,提高代码的可维护性和可扩展性。通过继承,可以将一些通用的方法和属性定义在父接口中,然后让多个子接口去继承这些通用的方法和属性,从而避免了重复编写相同的代码。
注意当接口继承接口时,子接口并不需要重写父接口的抽象方法,只有当类实现子接口时,才需要将子接口本来的抽象方法和父接口的抽象方法在该类中全部重写。
interface IRunning { void run(); } interface ISwimming { void swim(); } // 两栖的动物, 既能跑, 也能游 interface IAmphibious extends IRunning, ISwimming { } class Frog implements IAmphibious { ... }
通过接口继承创建一个新的接口 IAmphibious 表示 "两栖的". 此时实现接口创建的 Frog 类, 就要重写 run 方 法, 也需要重写 swim 方法.
接口间的继承相当于把多个接口合并在一起.
接口第一部分完结
那么到这里我们的接口第一部分就结束了:把该讲的语法大部分讲完了。之后将会给大家带来接口第二部分:接口使用实例,这部分会比较难点,不过只要努力坚持下去,一切困难都会被攻克的,一起加油吧!👊 👊
(我们可以认为接口是一个特殊的类,其有特定的规则,这样子就好记多了)