一、接口的基础语法
1、接口也是一种引用数据类型,编译之后也是一个class字节码文件。
2、接口是完全抽象的。
3、接口的定义:
- 【修饰符列表】 interface 接口名{
}
4、接口支持多继承,一个接口可以继承多个接口。
5、 类和类之间叫做继承,类和接口之间叫做实现(仍然可以看作继承),继承是由extends 关键字,实现使用implements关键字完成。
6、 一个类可以同时实现多个接口,这种机制弥补了java中类和类之间的单继承带来的缺陷
public class InterfaceTest01 {
public static void main(String[] args) {
//接口支持多态
C c = new D();
B b = new D();
}
}
// 定义接口
interface A{
}
interface B{
}
//接口支持多继承
interface C extends A,B{
}
//一个类可以实现多个接口
class D implements A,B,C{
}
7、接口中只有常量和抽象方法。
8、接口中所有的元素都是public修饰的。(都是公开的。)
9、接口中的抽象方法定义时:public abstract 修饰符可以省略。
10、接口中的常量的public static final 可以省略。
11、当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部实现(覆盖\重写)。(方法重写子类方法权限不能更低)
public class interfaceTest02 {
public static void main(String[] args) {
System.out.println(MyMath.PI);
//MyMath.G = 10;//报错,G为常量,无法修改.
}
}
interface MyMath{
//接口中只能有抽象方法和常量
//抽象方法
public abstract int sum(int a,int b);
int sub(int a,int b) ; //public abstract 可以省略
//常量
public static final double PI = 3.1425;
double G = 9.8; //public static final 可以省略
}
abstract class MyMath1 implements MyMath{
}
class MyMath2 implements MyMath{
// 需要实现接口中的方法
public int sum(int a,int b) {
return a+b;
}
public int sub(int a,int b) {
return a-b;
}
}
public class InterfaceTest03 {
public static void main(String[] args) {
//非抽象类继承接口可以使用多态
MyMath mm = new MyMath2();
//调用接口里面的方法(面向接口编程)
System.out.println(mm.sum(10,20));
}
}
12、两接口虽然没有继承关系,但是写代码时候,可以互转。编译器没意见。但是运行时候可能会出现:ClassCastException
public class InterfaceTest04 {
public static void main(String[] args) {
X x = new Z();
Y y = (Y)x;
//经测试:接口和接口之间在进行强制类型转换时候,没有继承关系,也可以强转。但是一定要注意,运行时可能会出现ClassCastException异常。
}
}
interface X{
}
interface Y{
}
class Z implements X{
}
二、接口在开发中的作用(解耦合)
- 接口在开发中的作用,类似于多态在开发中的作用。
- 面向抽象编程,不要面向具体编程,降低程序的耦合度,提高程序的扩展力。
- 接口是完全抽象的,而我们以后正好要求,面向抽象编程。面向抽象编程这句话以后就可以修改为:面向接口编程。
- 有了接口就有了可插拔。可插拔表示扩展力很强,不是焊接死的。
- 主板和内存条之间有插槽,这个插槽就是接口,内存条坏了,可以重新买一个换下来,这叫做高扩展性。(低耦合度。)
- 接口在现实世界中到处都是:usb接口,灯泡和灯口之间……. 接口是一个抽象的概念
面向接口编程,可以降低程序的耦合度,提高程序扩展力,符合OCP开发原则。接口是使用离不开多态。(接口+多态才可以达到降低耦合度)
接口可以解耦合。
任何一个接口都有调用者和实现者,接口可以将调用者和实现者解耦合。调用者面向接口调用,实现者面向接口编写与实现。
项目的开发,一般都是将项目分为多个模块,模块与模块之间都是通过接口链接,降低耦合度。
三、类型和类型之间的关系
is a (继承)、has a(关联)、 like a(实现)
- is a:
- Cat is a animal(猫是一个动物)
- 凡是能满足is a的表示“继承关系”。
- A extends B
- has a:
- I have a menu(我有一张菜单)
- 凡是满足has a关系的表示“关联关系”。“关联关系”通常以属性的形式存在。
- A{
B b;
}
- like a:
- Cook like a menu(厨师像一个菜单一样)
- 凡是满足like a关系的表示“实现关系”。实现通常是类实现接 口。
- A implements B
四、抽象类和接口在语法上的区别
- 抽象类是半抽象的,接口是完全抽象的。
- 抽象类中有构造方法,接口中没有构造方法。
- 类与类之间只能单继承,接口与接口之间支持多继承,一个类也可以同时实现多个接口。
- 接口中只允许出现常量和抽象方法
五、接口的简单测试
利用“菜单”接口,链接顾客与厨师
public class InterfaceTest06 {
public static void main(String[] args) {
ChinaCook chinaCook = new ChinaCook();
AmericCook americCooke = new AmericCook();
//使用接口,顾客与厨师之间不用直接对接。
//顾客1想吃西餐
Customer customer1 = new Customer(americCooke);
customer1.order();
//顾客2想吃中餐
Customer customer2 = new Customer(chinaCook);
customer2.order();
}
}
//菜单接口
interface FoodMenu{
void chaoJiDan();
void yuXiangRouSi();
}
//中国厨师
class ChinaCook implements FoodMenu{
public void chaoJiDan() {
System.out.println("中国厨师做西红柿炒鸡蛋!!!");
}
public void yuXiangRouSi() {
System.out.println("中国厨师做鱼香肉丝!!!");
}
}
//美国厨师
class AmericCook implements FoodMenu{
public void chaoJiDan() {
System.out.println("美国厨师做西红柿炒鸡蛋!!!");
}
public void yuXiangRouSi() {
System.out.println("美国厨师做西红柿炒鸡蛋!!!");
}
}
//顾客
class Customer{
//利用多态,使用接口引用,构造时指向子类对象,降低耦合度
//给顾客一个菜单。以属性形式存在
private FoodMenu foodMenu;
//无参构造
public Customer() {
}
//有参构造.
public Customer(FoodMenu foodMenu) {
this.foodMenu = foodMenu;
}
public FoodMenu getFoodMenu() {
return foodMenu;
}
public void setFoodMenu(FoodMenu foodMenu) {
this.foodMenu = foodMenu;
}
// 提供点菜方法
public void order() {
//同类中可以不调用get方法
foodMenu.chaoJiDan();
foodMenu.yuXiangRouSi();
}
}