接口
接口,也可以称为 接口类
接口:类似与上电脑主机上接口,用于连接对接其他子系统,相当于一个桥梁,用于连接两个系统。这个桥梁有一种约定,一种规则,一种能力。
完成一件事情:要求+实现
只关注约定,不关注具体实现。
接口的规则
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(); // 连接方法
}
}
面试题: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() {
}
}
结构图:
当前案例中,能不能将五个抽象方法全部书写在一个接口中呢?
不推荐,不可以,因为如果书写在一个接口中,将增加程序的耦合性,即任何一个手机子类实现了这个接口,将必须重写这个五个抽象方法,即拥有五个功能,将不能根据市场需求灵活的生产不同档次的手机产品。
接口思想
接口是一种能力
做这项工作需要一个钳工,钳工是一种能力,不关心具体是谁。
面向接口编程:体现在接口的方法上
程序设计时:
关心实现类有何能力,而不关系实现细节。
面向接口的约定而不考虑接口的具体实现。
新人时:
搬砖,而不是设计,增删改查。帮助文档,需求文档,具体体现在哪里,就是各种各样的接口。
这些接口中的各种抽象方法都已经定义完了:返回值,名称,参数,唯独没有就是怎么实现。
我们主要写的是实现类。给你几个接口,把实现类写一下。
考核,给你们相同的接口,写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) |
抽象类和接口的区别
相同点:
代表系统的抽象层
都不能实例化
都包含抽象方法
用于描述系统提供的服务,不必提供具体实现
不同点:
抽象类中可以书写 普通属性,普通方法,构造方法,静态方法。
接口中不能写普通方法,普通属性,静态方法,构造方法。
什么时候使用抽象类,什么情况使用接口。
当你想要描述一个事物本质的时候,需要属性于是需要使用抽象类。例如 宠物,人类,鸟。
当你想要关注一个某个行为的时候,需要使用接口。例如:吃饭,唱歌,洗澡,等。
面向对象设计原则
多用组合(实现),少用继承。推荐使用组合,即使用接口实现,因为类只能继承一个父类。
针对接口编程。
(开闭原则)程序应该对扩展开放,对修改源代码关闭。