接口
1. 接口的基本概念
- 接口:将一些抽象方法封装到一起,便形成了一个接口;当某个类需要使用这些方法时,便可以实现该接口,然后便可以使用这些方法了。
- 定义接口的基本语法:
interface 接口名 {
静态属性;
抽象方法;
}
- 类实现接口的基本语法:
class 类名 implements 接口名 {
重写接口的抽象方法;
}
- 总结:接口就是更加抽象的抽象类;接口实现了程序设计的多态和高内聚低耦合的设计思想。
- 特别说明:在jdk 8.0 之后,接口中可以有静态方法和默认方法(default 修饰)的存在,且只允许添加这两种。
*对接口的理解:
- 接口可以看做是父类的补充机制,可以对特定子类的功能进行扩展;接口也可以对某个需求设计进行规范。
- 举例来说,接口就像是一个包含了多个知识点(抽象方法)的技能,当某个人(某个子类)想要掌握这个技能的时候,就要把该技能的所有知识点都学会(重写抽象方法);同时,该技能可以对其知识点进行规范(比如知识点的名称、知识点的个数等等)。
2. 接口的注意事项和细节
(1)接口不能被实例化。
(2)接口中的所有的方法默认用 public 修饰符修饰(可以省略);接口中的抽象方法的abstract 关键字可以省略。
- void 方法名()== public abstract void 方法名()
(3)一个普通类实现接口,则必须重写接口中的所有抽象方法;抽象类实现一个接口,可以不用重写接口的抽象方法。
(4)一个类可以同时实现多个接口。
(5)接口中的属性,必须是 public static final 三者一起修饰的。
- int a = 1 == public static final int a = 1
(6)可以直接使用 接口名.属性 来访问接口中的属性。
(7)接口不可以继承类,但是可以继承多个其他的接口。
(8)接口的修饰符只能是 public 和 默认,和类的修饰符一样。
(9)若一个子类同时继承了父类和实现了一个接口,且父类和接口中存在同名的属性,则子类在调用该属性时,用 接口名.属性 表示调用接口,用 super.属性 表示调用父类。
3. 实现接口和继承关系的比较
(1)继承的价值主要在于:解决代码的复用性和可维护性。
(2)接口的价值主要在于:设计好各种规范(方法),让实现接口的类去具体实现这些规范(方法)。
(3)接口在一定程度上实现代码解耦:即接口规范性 + 动态绑定机制。
4. 接口的多态特性
- 接口的引用可以指向实现了接口的类的对象(并不是接口的实例化)。语法如下:
- 接口名 接口的引用 = new 类名();
4.1 接口的多态参数
- 可以将所有实现了接口的类的对象划分为同一组接口的引用(类比于继承的多态,可以将继承了同一个父类的所有子类的对象当做同一组父类的引用),然后将该引用作为方法的形参。
- 当传递给方法具体的类的对象作为实参时,根据动态绑定机制,可以调用正确的对象方法。
请比较接口的多态使用和继承的多态使用。
- 代码实现:
public class InterfacePolyParameter {
public static void main(String[] args) {
//接口的多态体现
//接口的引用 if01 可以指向 实现了IF接口的类的对象
IF if01 = new Monster();
if01 = new Car();
//继承体现的多态
//父类类型的变量 a 可以指向 继承AAA的子类的对象实例
AAA a = new BBB();
a = new CCC();
}
}
// 接口
interface IF {}
class Monster implements IF{}
class Car implements IF{}
// 父类
class AAA {}
class BBB extends AAA {}
class CCC extends AAA {}
4.2 接口的多态数组
- 可以将所有实现了接口的类的对象划分为同一组接口的引用(类比与类的多态,可以将继承了同一个父类的所有子类的对象当做同一组父类的引用)。
- 然后将该引用作为数组类型,创建一个数组,数组中的元素则可以是所有实现了接口的类的对象。
案例:给USB 数组中,存放 Phone 和 Camera 对象,Phone 类还有一个特有的方法 call(),请遍历USB 数组,如果是 Phone 对象,除了调用 USB 接口定义的方法外,还需要调用 Phone 特有的方法。
- 代码实现:
public class InterfacePolyArr {
public static void main(String[] args) {
//多态数组 -> 接口类型数组
Usb[] usbs = new Usb[2];
usbs[0] = new Phone_();
usbs[1] = new Camera_();
/*
给Usb数组中,存放 Phone 和 相机对象,Phone类还有一个特有的方法call(),
请遍历Usb数组,如果是Phone对象,除了调用Usb 接口定义的方法外,
还需要调用Phone 特有方法 call
*/
for(int i = 0; i < usbs.length; i++) {
usbs[i].work();// 动态绑定机制
// 需要进行类型的向下转型
if(usbs[i] instanceof Phone_) {// 判断他的运行类型是 Phone_
((Phone_) usbs[i]).call();
}
}
}
}
interface Usb {
void work();
}
class Phone_ implements Usb {
public void call() {
System.out.println("手机可以打电话...");
}
@Override
public void work() {
System.out.println("手机工作中...");
}
}
class Camera_ implements Usb {
@Override
public void work() {
System.out.println("相机工作中...");
}
}
4.3 接口的多态传递
-
如果A 接口继承了B 接口,而C 类实现了A 类,那么实际上相当于C 类也实现了B类。
-
代码实现:
public class InterfacePolyPass {
public static void main(String[] args) {
//接口类型的变量可以指向,实现了该接口的类的对象实例
IG ig = new Teacher();
//如果IG 继承了 IH 接口,而Teacher 类实现了 IG接口
//那么,实际上就相当于 Teacher 类也实现了 IH接口.
//这就是所谓的 接口多态传递现象.
IH ih = new Teacher();
}
}
// IH 接口
interface IH {
void hi();
}
// IG 接口继承了IH接口
interface IG extends IH{}
// 实现了IG 的类
class Teacher implements IG {
@Override
public void hi() {}
}
总结
- 本文是小白博主在学习B站韩顺平老师的Java网课时整理总结的学习笔记,在这里感谢韩顺平老师的网课,如有有兴趣的小伙伴也可以去看看。
- 本文详细解释了 接口 的概念与使用,并深入介绍了 接口 的注意事项和细节,希望小伙伴们看后能有所收获!
- 最后,如果本文有什么错漏的地方,欢迎大家批评指正!一起加油!!我们下一篇博文见吧!