
学完继承、学完多态,但面对汹涌而来🌊的接口,相信很多同学都不知所措,因此我耗费几天几夜的时间,搜寻大量书籍资料,苦心闭关钻研,写出了一篇关于Java的接口从入门小白到精通大佬的学习之路,相信这篇文章一定对您有所帮助📖
Java接口是一系列方法的声明,是一些方法特征的集合
Java中一个新增的知识点,而C++中没有,因为Java有一个缺陷就是不可以实现多继承,只可以单继承,这就限制了有些功能的使用,于是为了让Java也能有这种能力,因为提出了接口的概念但是在接口中,就只能有抽象方法以及常量,而且接口中所有抽象方法的访问权限都是public公开的,因为它也算是static静态方法,所以可以省略public和static这两个关键字了解了接口的基本概念之后,是不是很想知道一个接口时怎么去定义和实现呢,让我们马上来看一看吧
public interface Sport {
void run(); //跑步
void swim(); //游泳
}
class关键字换成inferface关键字,但是变得可不止这一种哦,接口可是有它的专属图表的🎇IDEA👉

eclipse👉

public class People implements Sport{
}
public class People implements Sport{
@Override
public void run() {
System.out.println("我会慢跑🏃");
}
@Override
public void swim() {
System.out.println("我会自由泳🏊");
}
}
【注意事项】
了解了接口的定义和实现之后,接下来我们来说一说接口有哪些特点以及其具体的作用
接口虽与抽象类相似,但是比抽象类更加抽象,却不需要写abstract关键字,因为接口中所有方法都是抽象的,因此可以省略这个关键字
接口中只可以有常量,而且都是public、static、final关键字修饰的【默认都有,可以不加】,但是不可以有变量

接口没有构造方法,因此不可以用new关键字去创建接口的对象,而是要用一个具体的类去implements实现这个接口
一个类可以实现多个接口,一个接口可以继承多个接口【有点抽象,上代码】
public interface Sport {
void run();
void competition();
}
public interface Law {
void rule();
}
public class PingPongMan implements Sport,Law{
private String name;
public PingPongMan(String name) {
this.name = name;
}
@Override
public void rule() {
System.out.println(name + "必须遵纪守法");
}
@Override
public void run() {
System.out.println(name + "必须参加训练");
}
@Override
public void competition() {
System.out.println(name + "必须参加比赛");
}
}
public class Test {
public static void main(String[] args) {
PingPongMan p = new PingPongMan("张继科");
p.run();
p.competition();
p.rule();
}
}

public interface Law {
void rule();
}
public interface People {
void sleep();
void eat();
}
public interface Sport extends Law,People{
void run();
void competition();
}
以上的这两个特点很重要,也是弥补了Java类不能多继承的缺陷
class Dog extends Animal implements Runnging,Drinking{
}
有些刚刚接触Java接口的小伙伴就很疑惑,这个接口到底是用来干嘛的呢,它究竟有什么具体的作用
首先我们来总的概括一下,其实就是一句话:【定义一个公共规范,实现一个统一访问】
攻击、点塔、补刀这些,但是LOL中157个英雄,假设它们都对应一个类,难道在每个英雄类中都去写这三个功能吗,那一定不会,这是就可以定义一个基本英雄功能接口,里面封装了所有英雄所具备的基本能力,然后所有英雄类都去访问这个接口就可以
初步入门了接口后,接下去我们就要了解接口与它的实现类之间所存在的逻辑框架关系,也就是类图,这可以进一步帮助我们去理解接口
统一建模语言(Unified Modeling Language,UML)是用来设计软件的可视化建模语言。可以帮助我们简单、统一、图形化、能表达软件设计中的动态与静态信息


在前面将多态的时候,讲到上转型对象时我有提到过接口回调这个东西,这在接口中是比较重要的,因此做一个区分
说了这么多概念,您对接口回调一定还没有一个很清晰的认识,接下去我们通过一个小案例一起来看看
public interface ShowMessage {
void show(String s);
}
public class TV implements ShowMessage {
@Override
public void show(String s) {
System.out.println("tvtvtvtvtv");
System.out.println(s);
System.out.println("tvtvtvtvtv");
}
}
public class PC implements ShowMessage {
@Override
public void show(String s) {
System.out.println("pcpcpcpcpc");
System.out.println(s);
System.out.println("pcpcpcpcpc");
}
}
public class test {
public static void main(String[] args) {
ShowMessage sm;
sm = new TV();
sm.show("TCL电视机打开了");
System.out.println("-----------");
sm = new PC();
sm.show("Lenovo台式机打开了");
}
}

讲完了接口回调,我们再来说一下函数接口与Lambda表达式
Lambda表达式,也可称为闭包。类似于JavaScript中的闭包,它是推动Java8发布的最重要的新特性
1、代码更加简洁
2、减少匿名内部类的创建,节省资源⭐
3、使用时不用去记忆所使用的接口和抽象函数
1、若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热才显示出效率优势)
2、不容易调试。
3、若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂⭐
然后我们再来了解一下函数式接口
定义方法如下
@FunctionalInterface //一旦加上这个注解必须是函数式接口,里面只能有一个抽象方法
interface Swimming{
void swim();
//void run();
}
public class LambdaDemo1 {
//Lambda表达式只能简化函数式接口的匿名内部类的写法形式
//Lambda表达式只能简化接口中只有一个抽象方法的匿名内部类形式
public static void main(String[] args) {
//实现了Swimming这个接口
Swimming s1 = new Swimming() {
@Override
public void swim() {
System.out.println("老师游泳贼溜");
}
};
go(s1);
go(new Swimming() {
@Override
public void swim() {
System.out.println("学生游泳很开心");
}
});
}
public static void go(Swimming s){
System.out.println("开始。。。");
s.swim();
System.out.println("结束。。。");
}
}
对于如何去进行一个简化,我们需要先了解其规则
然后我们就对上面的代码进行一个简化
Swimming s1 = new Swimming() {
// Swimming s1 = () ->{ //简化版
// System.out.println("老师游泳贼溜");
// };
Swimming s1 = () -> System.out.println("老师游泳贼溜"); //最终版
go(s1);
到这里大家可能还是没有看懂,那我们再来多看几个,就能懂了
public class LambdaDemo2 {
public static void main(String[] args) {
Integer[] ages = {66,99,33,78,12};
//Arrays.sort(ages); 默认升序
Arrays.sort(ages, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1; //降序
}
});
// Arrays.sort(ages, (Integer o1, Integer o2) ->{
// return o2 - o1; //降序
// }
// );
// Arrays.sort(ages, (o1, o2) ->{
// return o2 - o1; //降序
// }
// );
Arrays.sort(ages, (o1, o2) -> o2 - o1);
System.out.println("排序后的内容为:" + Arrays.toString(ages));
}
}
再来一个有关按钮监听事件ActionListener的匿名内部类形式简化
//Lambda表达式简化按钮监听器ActionListener的匿名内部类形式
public class LambdaDemo3 {
public static void main(String[] args) {
JButton btn = new JButton("登录");
//给登录按钮绑定点击时间监听器
// btn.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// System.out.println("登录一下~~~");
// }
// });
//
// btn.addActionListener((ActionEvent e) ->{
// System.out.println("登录一下~~~");
// }
// );
//
// btn.addActionListener((e) ->{
// System.out.println("登录一下~~~");
// }
// );
btn.addActionListener( e -> System.out.println("登录一下~~~"));
}
}
好,又看了两个小案例,这些您对Lambda表达式简化匿名内部类有了一个基本的认识了,接下来我们说一些小贴士
了解接口后,我们要开始第二层次,也就是理解接口,首先就是要进行思考,提出相应的问题
在本小节中,我会设置三个实战项目,从浅入深,层层递进,帮助大家来更好地理解接口在实际的应用中到底是如何去使用的
看到这个标题,你不会真的以为只是输出【Helllo World】吧,那是不会的,只是这个案例作为第一个,比较简易一些,帮助大家来回顾上面所学的知识点
上代码
public interface SpeakHello {
public void speak();
}
public class CPeople implements SpeakHello{
@Override
public void speak() {
System.out.println("你好");
}
}
public class EPeople implements SpeakHello{
@Override
public void speak() {
System.out.println("Hello");
}
}
public class Hello {
public void lookHello(SpeakHello speakHello){
speakHello.speak(); //实现接口回调
}
}
public class test {
public static void main(String[] args) {
Hello hello = new Hello();
hello.lookHello(new CPeople());
hello.lookHello(new EPeople());
hello.lookHello(new SpeakHello() {
@Override //匿名内部类
public void speak() {
System.out.println("Hello World");
}
});
//简化版
hello.lookHello(() -> System.out.println("H W")); //Lambda表达式
}
}
很夸张的一个标题,突然脑洞打开想到的,哈哈,和项目也是有一些联系🔒
上代码
public abstract class MotorVehicles {
abstract void brake(); //刹车功能
}
public interface ControlTemperature { //控制温度
void controlAirTemperature();
}
public interface MoneyFare { //收取费用
void charge();
}
public class Bus extends MotorVehicles implements MoneyFare{
@Override
void brake() {
System.out.println("公交车正在刹车");
}
@Override
public void charge() {
System.out.println("公交车正在计费");
}
}
public class Taxi extends MotorVehicles implements MoneyFare,ControlTemperature{
@Override
void brake() {
System.out.println("出租车正在刹车");
}
@Override
public void charge() {
System.out.println("出租车正在计费");
}
@Override
public void controlAirTemperature() {
System.out.println("出租车正在调节空调温度");
}
}
public class Cinema implements MoneyFare,ControlTemperature{
@Override
public void charge() {
System.out.println("电影院开始收费");
}
@Override
public void controlAirTemperature() {
System.out.println("电影院正在调节室内温度");
}
}
public class test {
public static void main(String[] args) {
//1.三个类定义对象
Bus bus = new Bus();
Taxi taxi = new Taxi();
Cinema cinema = new Cinema();
//2.两个接口声明对象
MoneyFare moneyFare;
ControlTemperature controlTemperature;
moneyFare = bus;
bus.brake();
moneyFare.charge();
System.out.println("--------");
controlTemperature = taxi;
moneyFare = taxi;
taxi.brake();
moneyFare.charge();
controlTemperature.controlAirTemperature();
System.out.println("--------");
moneyFare = cinema;
controlTemperature = cinema;
moneyFare.charge();
controlTemperature.controlAirTemperature();
//上述操作有体现接口回调
}
}
首先声明,这个项目不是我的,是从一位大佬那里拿来的,我将其重新实现做一个讲解,这是他的博客链接,大家可以去看看
上代码
public abstract class Animal {
public abstract String getName();
public abstract void move(String destination);
public abstract void drink();
}
public abstract class Mammal extends Animal{
}
public abstract class Reptile extends Animal{
}
public interface Huntable <T>{ //泛型接口
//不仅是动物可以捕猎,其他生物也是可以捕猎(增加了广泛性)
void hunt(T o);
public default int max(int a,int b){
return a > b ? a : b;
}
}
public class Tiger extends Mammal implements Huntable<Animal>{
private String name = "Tiger";
@Override
public String getName() {
return this.name;
}
@Override
public void move(String destination) {
System.out.println(name + " move to the " + destination);
}
@Override
public void drink() {
System.out.println("Tiger lower it's head and drinks");
}
@Override
public void hunt(Animal animal) {
System.out.println("Tiger catched the " + animal.getName() + " and eat it");
}
}
public class Goat extends Mammal{
private String name = "Goat";
@Override
public String getName() {
return this.name;
}
@Override
public void move(String destination) {
System.out.println(name + " move to the " + destination);
}
@Override
public void drink() {
System.out.println("Goat lower it's head and drinks");
}
}
public class Rabbit extends Mammal{
private String name = "Rabbit";
@Override
public String getName() {
return this.name;
}
@Override
public void move(String destination) {
System.out.println(name + " move to the " + destination);
}
@Override
public void drink() {
System.out.println("Rabbit put out it's tongue and drinks");
}
}
public class Snake extends Reptile implements Huntable<Animal>{
private String name = "Snake";
@Override
public String getName() {
return this.name;
}
@Override
public void move(String destination) {
System.out.println(name + " move to the" + destination);
}
@Override
public void drink() {
System.out.println(name + "dived into water and drinks");
}
@Override
public void hunt(Animal animal) {
System.out.println("Snake catched the " + animal.getName() + " and eat it");
}
}
public class Farmer {
public void BringWater(String desination)
{
System.out.println("Farmer bring the water to the " + desination);
}
public void FeefWater(Animal animal)
{
BringWater("Farm");
animal.move("Farm");
animal.drink();
System.out.println("----------");
}
public void work()
{
Farmer farmer = new Farmer();
Tiger tiger = new Tiger();
Goat goat = new Goat();
Rabbit rabbit = new Rabbit();
farmer.FeefWater(tiger);
farmer.FeefWater(goat);
farmer.FeefWater(rabbit);
}
public void BringAnimal(Animal animal,String desination)
{
System.out.println("Farmer bring the " + animal.getName() + " to the " + desination);
}
// public void FeedAnimal(Animal hunter,Animal prey)
// {
// BringAnimal(prey,"Farm");
// hunter.move("Farm");
// Huntable huntable = (Huntable) hunter;
// huntable.hunt(prey);
// System.out.println("----------");
// }
public void FeedAnimal(Huntable huntable,Animal prey)
{
BringAnimal(prey,"Farm");
Animal animal = (Animal) huntable;
animal.move("Farm"); //多态
huntable.hunt(prey); //接口回调
System.out.println("----------");
}
}
public class test {
public static void main(String[] args) {
Farmer farmer = new Farmer();
farmer.work();
Tiger tiger = new Tiger();
Snake snake = new Snake();
Rabbit rabbit = new Rabbit();
Goat goat = new Goat();
farmer.FeedAnimal(tiger,goat);
farmer.FeedAnimal(snake,rabbit);
}
}
对于这个项目,我觉得对于接口的深入理解非常好的一个项目,我这里给大家做一个详细的分析
work()方法的运行结果
FeedAnimal方法的运行结果
思路分析
代码分析
public void BringAnimal(Animal animal,String desination)
{
System.out.println("Farmer bring the " + animal.getName() + " to the " + desination);
}
// public void FeedAnimal(Animal hunter,Animal prey)
// {
// BringAnimal(prey,"Farm");
// hunter.move("Farm");
// Huntable huntable = (Huntable) hunter;
// huntable.hunt(prey);
// System.out.println("----------");
// }
public void FeedAnimal(Huntable huntable,Animal prey)
{
BringAnimal(prey,"Farm");
Animal animal = (Animal) huntable;
animal.move("Farm"); //多态
huntable.hunt(prey); //接口回调
System.out.println("----------");
}
public class Tiger extends Mammal implements Huntable<Animal>
public class Snake extends Reptile implements Huntable<Animal>
OK,说完这三个实战案例,相信你对Java中的接口如何使用变得更加清楚,知道了接口的真正作用,了解到定义接口的真正含义
看到这里【接口】,你一定是学会了,让我们来做一个总结。
以上就是本文所有展现的所有内容,感谢您对本文的观看,如果疑问请于评论区留言或私信指出,谢谢🌷
以下是我开创的社区,感兴趣的小伙伴们可以加入进来一起交流学习,解决编程的难题
我的社区:🔥烈火神盾🔥