Java第二阶段---13抽象类和接口---第二节 接口
1.概念
在软件工程中,软件与软件的交互很重要,这就需要一个约定。每个程序员都应该能够编写实现这样的约定。接口就是对约定的描述
在java编程预言中,接口是类似于类的引用类型,它只能包含常量,方法签名,默认方法和嵌套类型。方法主题仅适用于默认方法和静态方法。接口无法实例化-它们只能由类实现或由其它接口扩展。
接口声明可以包含方法签名,默认方法,静态方法,和常量定义。具有实现的方法是默认方法和静态方法。
从上面的描述中可以得出:接口中没有构造方法。--->当然不能被实例化(即不能直接new对象出来) 那怎么办呢?-->只能用类来实现接口,就好比抽象类一样要用一个子类来继承这个抽象类,然后可以用抽象类来造对象的引用,直接用子类造对象赋给它,这个引用赋给我这个地址就行了,接口也是一样的。
2.接口定义
语法
[public] interface 接口名{ //[]表示可有可无
[public static final]数据类型 变量名 = 变量的值;//接口中定义变量,接口中定义的变量都是属于静态常量(在初始化的时候必须赋值),在定义的时候必须赋值 //变量是斜着的 是默认省略了public static final,接口中的变量 一定是public,因为除了public 其它的不能访问
返回值类型 方法名([参数列表]);//定义接口方法 没有方法体-->说明是抽象方法(即把前面public abstract省略了)
default 返回值类型 方法名([参数列表]){//接口中定义的默认方法,必须在JDK8及以上版本使用 接口中的东西都是属于公开的 即默认有public
[return 返回值;]
}
static 返回值类型 方法名([参数列表]){//接口中定义的默认方法,必须在JDK8及以上版本使用
[return 返回值;]
}
private 返回值类型 方法名([参数列表]){//接口中定义的默认方法,必须在JDK9及以上版本使用
[return 返回值;]
}
}
package com.cyx.interfaceclass;
interface Test {
public static final int number = 10;
public abstract void show();
public default int plus(int a,int b){
return a+b;
}
public static int multiply(int a ,int b){
return a*b;
}
//在接口中一般很少定义私有的方法,因为私有的方法只能在上面的方法中调用
private String getName(){
return "admin";
}
}
示例
使用接口描述人有名字
package com.cyx.interfaceclass.person;
public interface Person {
String getName();//获取人姓名
}
使用接口描述演员能表演
package com.cyx.interfaceclass.person;
public interface Actors {
void performance();//演员表演
}
使用接口描述歌手能唱歌
package com.cyx.interfaceclass.person;
public interface Singer {
void sing();//唱歌
}
使用接口描述艺人能代言
package com.cyx.interfaceclass.person;
public interface Artist {
void endorsement();//代言
}
3.接口继承
语法
[public] interface 接口名 extends 接口名1,接口名2,...接口名n{
}
注意:接口可以多继承,这是java中唯一可以使用多继承的地方。如果要使用多继承 则一定要使用接口,因为类只能够单继承。
示例
使用接口继承描述演员是人
package com.cyx.interfaceclass.person;
public interface Actors extends Person {
void performance();//演员表演
}
使用接口继承描述歌手是人
package com.cyx.interfaceclass.person;
public interface Singer extends Person {
void sing();//唱歌
}
使用接口继承描述艺人既是演员也是歌手
package com.cyx.interfaceclass.person;
public interface Artist extends Actors,Singer {
void endorsement();//代言
}
注意:接口可以多继承,这是Java中唯一可以使用多继承的地方。接口包含的变量都是静态常量,接口中包含的方法签名都是公开的抽象犯法,接口中的默认方法和静态方法在JDK8及以上版本才能定义,接口的私有方法必须在JDK9及以上版本才能定义。接口编译完成后也会生成相应的class文件。
4.接口实现
实现接口语法
访问修饰符 class 类名 implements 接口名1,接口名2,...,接口名n{
}
实现接口的类必须实现接口中声明的所有方法。
一个类如果实现了一个接口,那么就必须实现这个接口中定义的所有抽象方法(包括接口通过继承关系继承过来的抽象方法),这个类被称为接口的实现类或者说子类,与继承关系一样,实现类与接口之间的关系是is-a的关系。
示例
使用实现接口的方式描述娱乐明星是艺人
package com.cyx.interfaceclass.person;
public class EntertainmentStar implements Artist{
private String name;
public EntertainmentStar(String name) {
this.name = name;
}
@Override
public void endorsement() {
System.out.printf("娱乐明星%s代言\n",getName());
}
@Override
public void performance() {
System.out.printf("娱乐明星%s表演\n",getName());
}
@Override
public void sing() {
System.out.printf("娱乐明星%s唱歌\n",getName());
}
@Override
public String getName() {
return name;
}
}
package com.cyx.interfaceclass.person;
public class PersonTest {
public static void main(String[] args) {
Person p = new EntertainmentStar("刘德华");//娱乐明星是人
System.out.println(p.getName());
Actors a = new EntertainmentStar("范冰冰");//娱乐明星是演员
a.performance();
Singer s = new EntertainmentStar("张学友");//娱乐明星是歌手
s.sing();
Artist artist = new EntertainmentStar("古天乐");//娱乐明星是艺人
artist.endorsement();
artist.performance();
artist.sing();
}
}
5.接口应用场景
一般来说,定义规则、定义约定时使用接口
示例
计算机对外暴露有USB接口,USB接口生产商只需要按照接口的约定生产相应的设备(比如USB键盘、USB鼠标、优盘)即可。
USB接口定义:
package com.cyx.interfaceclass.usb;
public interface USB {
void service();//USB接口服务
}
USB键盘遵守接口的约定,也就是实现这个接口
package com.cyx.interfaceclass.usb;
public class KeyBoard implements USB {
@Override
public void service() {
System.out.println("键盘已接入,可以开始打字了");
}
}
USB鼠标遵守接口的约定,也就是实现这个接口
package com.cyx.interfaceclass.usb;
public class Mouse implements USB{
@Override
public void service() {
System.out.println("鼠标已接入,可以开始移动光标了");
}
}
优盘遵守接口的约定,也就是实现这个接口
package com.cyx.interfaceclass.usb;
public class UDisk implements USB {
@Override
public void service() {
System.out.println("优盘已接入,可以开始存储数据了");
}
}
电脑拥有USB接口
package com.cyx.interfaceclass.usb;
public class Computer {
private USB[] usbArr = new USB[4];
public void inserUsb(int index,USB usb){
if(index<=0||index>=usbArr.length){
System.out.println("请不要瞎搞");
}
else{
usbArr[index] = usb;
usb.service();
}
}
}
测试
package com.cyx.interfaceclass.usb;
public class ComputerTest {
public static void main(String[] args) {
Computer computer = new Computer();
computer.inserUsb(1,new Mouse());
}
}
练习
打印机对外暴露有墨盒(颜色)和纸张(大小)接口,墨盒生产商按照墨盒接口的约定生产黑白墨盒和彩色墨盒,纸张生产商按照纸张接口的约定生产A2纸和A4纸张。
package com.cyx.interfaceclass.printer;
/**
* 墨盒
*/
public interface InkBox {
String getColor();//获取墨盒的颜色
}
package com.cyx.interfaceclass.printer;
public class BlackInkBox implements InkBox{
@Override
public String getColor() {
return "黑白";
}
}
package com.cyx.interfaceclass.printer;
public class ColorInkBox implements InkBox {
@Override
public String getColor() {
return "彩色";
}
}
package com.cyx.interfaceclass.printer;
/**
* 纸张
*/
public interface Paper {
String getSize();//获取大小
}
package com.cyx.interfaceclass.printer;
public class A2Paper implements Paper{
@Override
public String getSize() {
return "A2";
}
}
package com.cyx.interfaceclass.printer;
public class A4Paper implements Paper{
@Override
public String getSize() {
return "A4";
}
}
package com.cyx.interfaceclass.printer;
/**
* 打印机
*/
public class Printer {
//打印机有墨盒接口 先找接口
private InkBox inkBox;
private Paper paper;
//打印机造出来的时候就只是暴露了两个接口 可能接口上没东西 所以可以生成一个构造方法,无参构造
public Printer() {
}
public Printer(InkBox inkBox, Paper paper) {
this.inkBox = inkBox;
this.paper = paper;
}
public void print(){
System.out.printf("打印机使用%s墨盒在%s纸张上打印\n",inkBox.getColor(),paper.getSize());
}
//生成的是没有的 需要这样的方式来放置纸张
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;
}
}
package com.cyx.interfaceclass.printer;
public class PrinterTest {
public static void main(String[] args) {
Printer p1 = new Printer();
p1.setPaper(new A4Paper());
p1.setInkBox(new ColorInkBox());
p1.print();
Printer p2 = new Printer(new BlackInkBox(),new A2Paper());
p2.print();
}
}