10.1 基础语法及概念
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。(Java中的继承:一个类只能有一个父类 B 继承 A C 继承B D 继承C 不能多继承意思是D 不能同时继承A,B,C。Java为了解决单继承的缺陷,出现了接口,一个类可以实现多个接口,多个之间用逗号分隔) B实现A A(接口) B(实现类)
接口是抽象方法的集合,接口中的抽象方法不需要使用abstract来进行修饰
语法
public interface 接口名{
方法的定义
public void show(); //定义出来的方法一定是抽象方法 不能有实现
}
对于接口而言不叫继承,叫实现,哪个类要继承接口,叫做实现接口,也称为这个接口的实现类
实现语法
public class 类名 implements 接口名,接口名1,接口名2{
}
实现类实现的接口中的方法必须要重写,这个重写过程就是实现,因为接口中只有方法的定义,实现类中必须对这些方法实现具体的代码。
java面向对象编程,java面向接口编程, java面向Spring编程。
接口拥有用于对原来的程序进行功能扩充的能力,必须要注意,以后的框架很多都要求以接口的形式出现。OOP设计模式。
基础语法案例:
代码语言:javascript复制package com.qf.interface1;
public interface StudentInterface {
public void show();
public void study();
}
代码语言:javascript复制package com.qf.entitys;
import com.qf.interface1.StudentInterface;
public class Student implements StudentInterface {
private String name;
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void show() {
System.out.printf("姓名:%s,电话:%sn",this.name,this.phone);
}
public void study() {
System.out.printf("%s同学在认真的学习",this.name);
}
}
代码语言:javascript复制public class Start {
public static void main(String[] args) {
Student student=new Student();
student.setName("张三");
student.setPhone("13321345678");
student.show();
student.study();
}
}
接口也能实现多态,用接口对象去存放实现类的实例。例如:
代码语言:javascript复制StudentInterface stu=new Student();
stu.show();
stu.study();
基础案例:
Java模拟电脑。电脑开机, 关机,USB接口 --> 键盘,鼠标(输入设备), U盘 , 移动硬盘(输入输出设备),显示器,音响(输出设备)
代码语言:javascript复制package com.qf.interface1;
//USB接口
public interface USB {
//传入
public void input();
//传出
public void output();
}
代码语言:javascript复制package com.qf.entitys;
import com.qf.interface1.USB;
//电脑
public class Computer {
private USB usb1;
private USB usb2;
private USB usb3;
public USB getUsb1() {
return usb1;
}
public void setUsb1(USB usb1) {
this.usb1 = usb1;
System.out.println("usb1已接入,驱动安装完成");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public USB getUsb2() {
return usb2;
}
public void setUsb2(USB usb2) {
this.usb2 = usb2;
System.out.println("usb2已接入,驱动安装完成");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public USB getUsb3() {
return usb3;
}
public void setUsb3(USB usb3) {
this.usb3 = usb3;
System.out.println("usb3已接入,驱动安装完成");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//表示电脑是否打开
private boolean isopen=false;
//开机
public void start() {
System.out.print("正在开机");
for (int i = 1; i <=5 ; i ) {
System.out.print(".");
try {
Thread.sleep(1000);//程序在这里会暂停1秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("进入系统");
isopen=true;
}
//电脑的操作,电脑的操作一定要在开机状态下完成
public void ctrl(){
if(isopen){
if(usb1!=null) {
usb1.output();
usb1.input();
}
System.out.println("=====================================");
if(usb2!=null) {
usb2.output();
usb2.input();
}
System.out.println("=====================================");
if(usb3!=null) {
usb3.output();
usb3.input();
}
}
}
//关机
public void close(){
System.out.println("关闭系统");
isopen=false;
}
}
代码语言:javascript复制package com.qf.entitys;
import com.qf.interface1.USB;
public class KeyBoard implements USB {
public void input() {
System.out.println("键盘开始输入...");
}
public void output() {
System.out.println("键盘灯亮...");
}
}
代码语言:javascript复制package com.qf.entitys;
import com.qf.interface1.USB;
public class Mouse implements USB {
public void input() {
System.out.println("鼠标开始操作");
}
public void output() {
System.out.println("鼠标灯亮了...");
}
}
代码语言:javascript复制package com.qf.entitys;
import com.qf.interface1.USB;
public class UBoard implements USB {
public void input() {
System.out.println("将U盘中的文件传入电脑中");
}
public void output() {
System.out.println("将电脑中的文件传入U盘中");
}
}
代码语言:javascript复制package com.qf.com.qf.Main;
import com.qf.entitys.Computer;
import com.qf.entitys.KeyBoard;
import com.qf.entitys.Mouse;
import com.qf.entitys.UBoard;
public class Start {
public static void main(String[] args) {
Computer computer=new Computer();
KeyBoard keyBoard=new KeyBoard();
Mouse mouse=new Mouse();
UBoard uBoard=new UBoard();
computer.start();
computer.setUsb1(keyBoard);
computer.setUsb2(mouse);
computer.setUsb3(uBoard);
computer.ctrl();
computer.close();
}
}
10.2 多态
计算案例1、
代码语言:javascript复制package com.qf.clac;
public interface Calculation {
//定义计算接口
public int clac(int num1,int num2);
}
加,减,乘,除,取余五个实现类来实现这个接口
代码语言:javascript复制package com.qf.clac.impl;
import com.qf.clac.Calculation;
public class Addition implements Calculation {
public int clac(int num1, int num2) {
return num1 num2;
}
}
代码语言:javascript复制package com.qf.clac.impl;
import com.qf.clac.Calculation;
public class Division implements Calculation {
public int clac(int num1, int num2) {
if(num2==0){
//人为的抛出一个异常
throw new RuntimeException("除数不能为0");
}
return num1/num2;
}
}
代码语言:javascript复制package com.qf.clac.impl;
import com.qf.clac.Calculation;
public class Multiplication implements Calculation {
public int clac(int num1, int num2) {
return num1*num2;
}
}
代码语言:javascript复制package com.qf.clac.impl;
import com.qf.clac.Calculation;
public class Residual implements Calculation {
public int clac(int num1, int num2) {
if(num2==0){
//人为的抛出一个异常
throw new RuntimeException("除数不能为0");
}
return num1%num2;
}
}
代码语言:javascript复制package com.qf.clac.impl;
import com.qf.clac.Calculation;
public class Subtraction implements Calculation {
public int clac(int num1, int num2) {
return num1-num2;
}
}
代码语言:javascript复制package com.qf.start;
import com.qf.clac.Calculation;
import com.qf.clac.impl.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int num1=input.nextInt();
System.out.println("请输入一个符号:");
char f=input.next().charAt(0);
System.out.println("请输入第二个数:");
int num2=input.nextInt();
Calculation calculation=null;
switch (f){
case ' ':
calculation=new Addition();
break;
case '-':
calculation=new Subtraction();
break;
case '*':
calculation=new Multiplication();
break;
case '/':
calculation=new Division();
break;
case '%':
calculation=new Residual();
break;
}
int clac = calculation.clac(num1, num2);
System.out.println(clac);
}
}
加入了设计模式的案例,接口现实在上面:
代码语言:javascript复制package com.qf.start;
import com.qf.service.CalcService;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int num1=input.nextInt();
System.out.println("请输入一个符号:");
char f=input.next().charAt(0);
System.out.println("请输入第二个数:");
int num2=input.nextInt();
CalcService calcService = new CalcService();
int calc = calcService.Calc(num1, f, num2);
System.out.println(calc);
}
}
代码语言:javascript复制package com.qf.service;
import com.qf.clac.Calculation;
import com.qf.clac.entitys.CalcMap;
import com.qf.clac.impl.*;
public class CalcService {
//这里做计算功能,但是不是具体的计算,只是根据符号去调用上体计算类里的计算功能
public int Calc(int num1,char f,int num2){
Calculation calculation=getCalculation(f); //factoryBean(f); //调用获取计算类对象的方法
if(calculation!=null) {
int clac = calculation.clac(num1, num2);
return clac;
}else{
//抛出一个异常 返回一个具体的值是不对的,有可能人家的计算结果就是这个值呢 0 -1
throw new RuntimeException("输入的符号错误");
}
}
/**
* 根据输入的符号获取对应的计算类对象 策略模式
* @param f 符号
* @return 计算类的对象
*/
private Calculation getCalculation(char f){
//循环这个所有可能性的数组
for (CalcMap c: calcUtilsArr) {
//用户输入的符号与数组哪一个匹配
if(c.getF()==f){
//如果匹配就将对应的具体的计算类的对象返回
return c.getCalculation();
}
}
//如果没有找到返回一个null
return null;
}
//将用于存放所有计算的可能性, CalcMap 有两个属性 一个符号,一个具体的计算操作类
private CalcMap[] calcUtilsArr=new CalcMap[5];
/*
设计模式策略模式 Map HashMap()
*/
public CalcService(){
/*Calculation add=new Addition();
CalcMap addMap=new CalcMap(' ',add);*/
//在CalcService 这里创建的时候就将这个数组初始化好
calcUtilsArr[0]=new CalcMap(' ',new Addition());
calcUtilsArr[1]=new CalcMap('-',new Subtraction());
calcUtilsArr[2]=new CalcMap('*',new Multiplication());
calcUtilsArr[3]=new CalcMap('/',new Division());
calcUtilsArr[4]=new CalcMap('%',new Residual());
}
//简单工厂
private Calculation factoryBean(char f){
Calculation calculation=null;
switch (f){
case ' ':
calculation=new Addition();
break;
case '-':
calculation=new Subtraction();
break;
case '*':
calculation=new Multiplication();
break;
case '/':
calculation=new Division();
break;
case '%':
calculation=new Residual();
break;
}
return calculation;
}
}
代码语言:javascript复制package com.qf.clac.entitys;
import com.qf.clac.Calculation;
public class CalcMap {
public CalcMap(char f, Calculation calculation) {
this.f = f;
this.calculation = calculation;
}
private char f; //键 key // 代号 我要根据这里的键这取值 k-v 键值对
private Calculation calculation; //具体的人 这里是我具体要用的内容
public char getF() {
return f;
}
public void setF(char f) {
this.f = f;
}
public Calculation getCalculation() {
return calculation;
}
public void setCalculation(Calculation calculation) {
this.calculation = calculation;
}
}
10.3 接口中的静态常量
接口中可以定义成员属性,但是接口中定义出来的成员属性有两个默认修饰 static final ,所以接口中的成员属性默认就是静态和终态变量。静态常量。
代码语言:javascript复制package com.qf.interface2;
public interface StudentInterface {
//public static final String name="张三";
String name="张三";//默认自带 static final
public void study();
}
10.4 接口的规范
1、一个类可以同时实现多个接口,多个接口这间用逗号分隔(掌握)
代码语言:javascript复制public class Student implements StudentInterface, PeopleInterface {
//这是来自学生接口中
public void study() {
System.out.println(StudentInterface.name "在学习");
}
//下面这两个方法是实现人类接口中的
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
2、接口不能直接被接口自己实例化,它与抽象类同理,接口对象只能被实现类实例化。(掌握)
代码语言:javascript复制public class Main {
public static void main(String[] args) {
// StudentInterface studentInterface=new StudentInterface();这样对接口创建接口对象是不对的,语法通不过
//很少会在同一地方去同时调用不同接口中的方法 ,一般都是在不同的地方调用实现类中的接口方法
PeopleInterface student=new Student();
student.sleep();
student.eat();
//如果你真的要在同一地方调用所有接口中的方法时,请进行拆箱操作
StudentInterface stu=(StudentInterface) student;
stu.study();
}
}
3、一个接口可以去继承另一个接口,继承之后子接口中就拥有了父接口中定义的方法(掌握)
代码语言:javascript复制public interface StudentInterface extends PeopleInterface {
public static final String name="张三";
public void study();
}
package com.qf.interface2.impl;
import com.qf.interface2.PeopleInterface;
import com.qf.interface2.StudentInterface;
//这里Student只实现了StudentInterface接口,但是实现的方法必须把PeopleInterface中定义的方法一起实现
//因为StudentInterface和PeopleInterface是父子关系。
public class Student implements StudentInterface {
//这是来自学生接口中
public void study() {
System.out.println(StudentInterface.name "在学习");
}
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
4、一个类不能实现多继承,但是接口可以多继承(了解)
代码语言:javascript复制父接口
package com.qf.interface2;
public interface PeopleInterface {
public void eat();
public void sleep();
}
package com.qf.interface2;
public interface TeacherInterface {
public void subject();
}
代码语言:javascript复制子接口
//StudentInterface extends PeopleInterface,TeacherInterface 这里学生接口继承了多个父接口
public interface StudentInterface extends PeopleInterface,TeacherInterface {
public static final String name="张三";
public void study();
}
实现类
代码语言:javascript复制//必须实现这个接口中所有的父接口定义的方法
public class Student implements StudentInterface {
//这是来自学生接口中
public void study() {
System.out.println(StudentInterface.name "在学习");
}
//这是父接口People中的两个方法
public void eat() {
}
public void sleep() {
}
//这是父接口Teacher中的一个方法
public void subject() {
}
}
5、接口中的方法不能有具体的实现,但是默认方法和静态方法可以有具体的实现(了解)
代码语言:javascript复制package com.qf.interface2;
public interface StudentInterface {
public static final String name="张三";
//接口定义的方法
public void study();
//默认方法,可以有实现
default void eat(){
System.out.println(name "吃饭");
}
//静态方法,可以有实现
static void sleep(){
System.out.println(name "睡觉");
}
}
代码语言:javascript复制public class Main {
public static void main(String[] args) {
//接口中静态方法的调用
StudentInterface.sleep();
StudentInterface stu=new Student();
stu.eat(); //接口默认方法的调用
}
}