Skip to main content

接口

接口,也可以称为 接口类

接口:类似与上电脑主机上接口,用于连接对接其他子系统,相当于一个桥梁,用于连接两个系统。这个桥梁有一种约定,一种规则,一种能力。

完成一件事情:要求+实现
只关注约定,不关注具体实现。

接口的规则

1、接口中的方法默认都为全局抽象方法,即不管是否书写均使用 public abstract 修饰。

2、 接口不能直接new对象,必须通过new实现类(子类)的方式创建对象 (多态向上转型)。

3、 实现类(子类)必须实现(重写)接口中的所有抽象方法,除非实现类是 抽象类 或者 是 接口

4、 接口中不能书写普通属性、普通方法、构造方法、静态方法。

5、 一个类只能继承一个父类,一个实现类可以实现多个接口,接口也可以继承多个接口。

6、 接口实现多态的方式与之前一致。

接口的示例:

package com.interfacePart.Test01;

public interface Usb {
// 接口内 默认为 全局静态变量 即 public static final 修饰
int A = 100;
// 接口中的方法默认都为全局抽象方法 即不管是否书写均使用public abstract修饰
void connect();
}
package com.interfacePart.Test01;

public class Mouse implements Usb{
@Override
public void connect() {
System.out.println("鼠标已连接~");
}
}
package com.interfacePart.Test01;

// 定义一个抽象类,实现接口
public abstract class Converter implements Usb{
// 转换方法:将水晶头转为usb接口
public abstract void convert();
}
package com.interfacePart.Test01;

public class UgreenConverter extends Converter{
@Override
public void convert() {
System.out.println("绿联转换器执行水晶头转换USB接口");
}

@Override
public void connect() {
System.out.println("绿联转换器连接USB接口~");
}
}
package com.interfacePart.Test01;

public class TestUsb {
public static void main(String[] args) {
// Usb usb = new Usb() // 报错,接口不能 new 对象
Usb usb = new Mouse(); // 只能通过new 子类(实现类)对象 创建对象,父类引用指向子类对象,多态向上转型的方式
usb.connect(); // 调用实现类中重写的方法。

// 顶层父类Usb中 只有 connect 方法
Usb converter = new UgreenConverter();
converter.connect(); // 链接方法

// 创建一个转换器对象
Converter converter1 = new UgreenConverter();
converter1.convert(); // 转换方法
converter1.connect(); // 连接方法

}
}

image-20250707142122523

面试题:Java支持多继承?

不支持 但是可以使用接口继承多个接口的方式 实现类似多继承的效果

实现类

由 implement 关键字 实现父类功能的类 称之为 实现类

实现类的功能和子类的功能一样,由于使用了关键字不同,叫法不同。

实现类必须实现(重写)父类中(接口)中的所有抽象方法,除非实现类本身也是抽象类或者接口。

public class Mouse implement USB {

}

多实现,多继承示例:

package com.interfacePart.Test02;

public interface A {
void m1();
}

interface B{
void m2();
}

interface C{
void m3();
}

interface D{
void m4();
}

// 一个接口可以继承多个接口,这种情况很少出现。
interface F extends A,B,C,D{
void m5();
}

// 一个类 可以 实现多个接口
class E implements A,B,C,D{
// 实现4个方法
@Override
public void m1() {

}

@Override
public void m2() {

}

@Override
public void m3() {

}

@Override
public void m4() {

}
}

结构图:

image-20250707142246657

当前案例中,能不能将五个抽象方法全部书写在一个接口中呢?

不推荐,不可以,因为如果书写在一个接口中,将增加程序的耦合性,即任何一个手机子类实现了这个接口,将必须重写这个五个抽象方法,即拥有五个功能,将不能根据市场需求灵活的生产不同档次的手机产品。

接口思想

接口是一种能力

做这项工作需要一个钳工,钳工是一种能力,不关心具体是谁。

面向接口编程:体现在接口的方法上

程序设计时:
关心实现类有何能力,而不关系实现细节。
面向接口的约定而不考虑接口的具体实现。

新人时:
搬砖,而不是设计,增删改查。帮助文档,需求文档,具体体现在哪里,就是各种各样的接口。
这些接口中的各种抽象方法都已经定义完了:返回值,名称,参数,唯独没有就是怎么实现。
我们主要写的是实现类。给你几个接口,把实现类写一下。
考核,给你们相同的接口,写3个实现类,看哪个实现类写的更好。
研发设计时,
需要什么功能,需要多长时间。
老板制定目标,提出要求,下边的人开始实现。

这样设计的好处:
把行为的要求和行为的实现分开了,一个要求(接口),有多个实现方式(实现类),更加灵活。

接口是一种约定


面向接口编程:
有些接口只有名称
程序设计时面对接口的约定而不考虑具体实现。

接口的理解

接口是一种能力,实现一个接口,即表示具备一个能力,实现多个接口,即表示具备多个能力。

关心实现类有何能力,而不关心实现细节

面向接口的约定而不考虑接口的具体实现

接口案例

接口是一种能力,接口就是功能。

每一项功能,都来写一个接口。

先继承,后实现。

public class xxx extends xxx inplements xxx {}

程序设计思想

接口的隔离性:一个接口实现一个功能。

接口实现手机

接口的理解

接口是一种能力,实现一个接口,即表示具备一个能力,实现多个接口,即表示具备多个能力。

关心实现类有何能力,而不关心实现细节

面向接口的约定而不考虑接口的具体实现

思路:

首先定义一个手机类 Phone 父类 抽象类
类中:
属性:品牌 型号 价格
方法:打电话 发短信 (抽象方法)
先封装,后构造,然后重写toString

定义一个普通手机 CommonPhone 类,继承手机类 Phone,实现音频,游戏,上网接口。
属性:键盘类型

定义一个智能手机 SmartPhone,继承手机类 Phone,实现音频,视频,游戏,拍照,上网接口。
属性:屏幕大小属性


按照接口就是一种能力的思想,定义接口
定义一个播放音频的接口 public interface Audio {}

定义一个播放视频的接口 public interface Video {}

定义一个拍照的接口 public interface Phone {}

定义一个玩游戏的接口 public interface Game{}

定义一个上网的接口 public interface InterNet{}

定义一个测试类
创建 smartPhone对象
调用功能
创建 commonPhone对象
调用功能
package com.interfacePart.Test03;

public class TestPhone {
public static void main(String[] args) {
// 创建一个 智能手机 对象
SmartPhone sp = new SmartPhone("一加","OnePlus 12 Prp",4299,6.3);
// 智能手机打电话
sp.call();
// 智能手机发短信
sp.sendMessage("睡了吗");
sp.playVideo("《小猪佩奇成人版》");
sp.playMusic("《最炫民族风》");
sp.playGames("《原神》");
sp.playPhoto();

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

CommonPhone cp = new CommonPhone("诺基亚", "N97", 8.8, "九键");

cp.sendMessage("有内鬼取消交易");
cp.call();
cp.playMusic("《发如雪》");
cp.playGames("《贪吃蛇》");
cp.playVideo("密码的周一能不能放过我这一次");

}
}

package com.interfacePart.Test03;

public abstract class Phone {
// 定义属性
private String brand;
private String type;
private double price;
// 封装

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}

public Phone() {
}

public Phone(String brand, String type, double price) {
this.brand = brand;
this.type = type;
this.price = price;
}

// 定义抽象方法
public abstract void call();
public abstract void sendMessage(String message);

@Override
public String toString() {
return "Phone{" +
"brand='" + brand + '\'' +
", type='" + type + '\'' +
", price=" + price +
'}';
}
}

package com.interfacePart.Test03;

public interface Game {
void playGames(String game);
}

package com.interfacePart.Test03;

public interface Music {
void playMusic(String audioName);
}

package com.interfacePart.Test03;

public interface Photo {
void playPhoto();
}

package com.interfacePart.Test03;

public interface Video {
void playVideo(String videoName);
}

package com.interfacePart.Test03;

public class SmartPhone extends Phone implements Game,Music,Video,Photo{
private double screenSize;

public double getScreenSize() {
return screenSize;
}

public void setScreenSize(double screenSize) {
this.screenSize = screenSize;
}

public SmartPhone() {
}

public SmartPhone(String brand, String type, double price, double screenSize) {
super(brand, type, price);
this.screenSize = screenSize;
}

@Override
public void playGames(String game) {
System.out.println("智能手机打游戏,体验很丝滑:" + game);
}

@Override
public void playMusic(String audioName) {
System.out.println("智能手机播放音频,音质很棒:" + audioName);
}

@Override
public void call() {
System.out.println("智能手机打电话,语音拨号,体验很不错");
}

@Override
public void sendMessage(String message) {
System.out.println("智能手机发短信,手写输入,体验很棒:" + message);
}

@Override
public void playVideo(String videoName) {
System.out.println("智能手机播放视频,很清晰:" + videoName);
}

@Override
public void playPhoto() {
System.out.println("光学长焦镜头,咔嚓一下记录美好,记录你我");
}
}

package com.interfacePart.Test03;

public class CommonPhone extends Phone implements Game,Music,Photo,Video{
private String keyboardType;

public String getKeyboardType() {
return keyboardType;
}

public void setKeyboardType(String keyboardType) {
this.keyboardType = keyboardType;
}

public CommonPhone() {
}

public CommonPhone(String brand, String type, double price, String keyboardType) {
super(brand, type, price);
this.keyboardType = keyboardType;
}

@Override
public void call() {
System.out.println("普通手机打电话,按键拨号,体验还行");
}

@Override
public void sendMessage(String message) {
System.out.println("普通手机发短信,按键打字,体验一般:" + message);
}

@Override
public void playGames(String game) {
System.out.println("普通手机打游戏,体验一般:" + game);
}

@Override
public void playMusic(String audioName) {
System.out.println("普通手机播放音乐,音质感人:" + audioName);
}

@Override
public void playPhoto() {
System.out.println("普通手机拍照画质很感人");
}

@Override
public void playVideo(String videoName) {
System.out.println("普通手机看视频,像素很低" + videoName);
}
}

打印机案例

接口也可以作为一种数据类型

接口是一种约定,即表示一种规范

程序设计时面向接口的约定而不考虑具体实现

思路:

开发打印机:

定义打印机类
属性:纸张,和墨盒
方法:

定义 纸张 接口
返回纸张型号
定义 A4纸张 实现类

定义 A5纸张 实现类


定义 墨盒 接口
墨盒型号

定义 黑白墨盒 实现类

定义 彩色墨盒 实现类

定义测试类
调用打印的方法
package com.interfacePart.Test04;

public class Printer {
// 接口也可以作为一种数据类型
private InkBox inkBox;
private Paper paper;

public InkBox getInkBox() {
return inkBox;
}

public void setInkBox(InkBox inkBox) {
this.inkBox = inkBox;
}

public Paper getPaper() {
return paper;
}

public void setPaper(Paper paper) {
this.paper = paper;
}

public Printer() {
}

public Printer(InkBox inkBox, Paper paper) {
this.inkBox = inkBox;
this.paper = paper;
}
// 定义实例打印方法
public void print(){
System.out.println("使用" + this.getInkBox().getInkBoxType() + "墨盒在" + this.getPaper().getPaperSize() + "纸张上打印");
}
}

package com.interfacePart.Test04;

public interface InkBox {
// 获取墨盒类型
String getInkBoxType();
}
package com.interfacePart.Test04;

public interface Paper {
// 获取纸张大小
String getPaperSize();
}
package com.interfacePart.Test04;

public class A4 implements Paper{
@Override
public String getPaperSize() {
return "A4";
}
}
package com.interfacePart.Test04;

public class B5 implements Paper{
@Override
public String getPaperSize() {
return "B5";
}
}
package com.interfacePart.Test04;

public class BlackInkBox implements InkBox{

@Override
public String getInkBoxType() {
return "黑色";
}
}
package com.interfacePart.Test04;

public class ColorInkBox implements InkBox{
@Override
public String getInkBoxType() {
return "彩色";
}
}
package com.interfacePart.Test04;

public class TestPrinter {
public static void main(String[] args) {
// 创建打印机实例
Printer hp = new Printer();
// 创建纸张实例
Paper a4 = new A4();
Paper b5 = new B5();
// 创建墨盒实例
InkBox blackInk = new BlackInkBox();
InkBox colorInk = new ColorInkBox();
// 设置打印机属性
hp.setPaper(a4);
hp.setInkBox(colorInk);
// 调用打印机实例属性
hp.print(); // 使用彩色墨盒在A4纸张上打印
}
}

接口总结

接口也可以作为一种类型使用。

继承和实现的区别

概念继承(extends)实现(implements)
含义一个类继承另一个类,获取其属性和方法一个类实现一个或多个接口,承诺提供接口中声明的方法的实现
关系“是一个”(is-a)“可以做某事”(can-do)

抽象类和接口的区别

相同点:
代表系统的抽象层
都不能实例化
都包含抽象方法
用于描述系统提供的服务,不必提供具体实现

不同点:
抽象类中可以书写 普通属性,普通方法,构造方法,静态方法。
接口中不能写普通方法,普通属性,静态方法,构造方法。

什么时候使用抽象类,什么情况使用接口。

当你想要描述一个事物本质的时候,需要属性于是需要使用抽象类。例如 宠物,人类,鸟。
当你想要关注一个某个行为的时候,需要使用接口。例如:吃饭,唱歌,洗澡,等。

面向对象设计原则

多用组合(实现),少用继承。推荐使用组合,即使用接口实现,因为类只能继承一个父类。
针对接口编程。
(开闭原则)程序应该对扩展开放,对修改源代码关闭。