1.知识点
2.根据接口的举出语法的实例代码
package com.baidu.com.jia.jiekou; /** * 1.接口(interface)在Java中表示一种规范或契约,它定义了一组抽象方法和常量,用来描述一些实现这个接口的类应该具有哪些行为和屈性。接口和类一样,也是一种引用数据类型。 * 2.接口怎么定义?[修饰符列表]interface 接口名{} * 3.抽象类是半抽象的,接口是完全抽象的。接口没有构造方法,也无法实例化。 * (抽象类是有构造方法的,因为构造方法是给子类用的,想super()方法就理解了。) * 4.(JDK8之前的语法规则)接口中只能定义:常量+抽象方法。接口中的常量的static final可以省略。接口中的抽象方法的abstract可以省略。接口中所有的方法和变量都是public修饰的。 * 5.接口直接可以多继承 * 6.类和接口的关系我们叫做实现(这里的实现也可以等同看做继承)。使用implements关键字进行接口的实现。 * 7.一个非抽象的类实现接口必须将接口中所有的抽象方法全部实现(强制要求的,必须的,要不然编译器报错). * 8.一个类可以实现多个接口。 语法是:class 类 implements 接口A,接口B{} * 9.Java之后,接口中允许出现默认方法和静态方法(JDK8新特性) * 默认方法:引入默认方式是为了解决接口演变问题:接口可以定义抽象方法,但是不能实现这些方法。 * 所有实现接口的类都必须实现这些抽象方法。 * 这会导致接口升级的问题:当我们向接口添加或删除一个抽象方法时,这会破坏该接口的所有实现, * 并且所有该接口的用户都必须修改其代码才能适应更改。这就是所谓的”接口演变”问题 * 静态方法:注意:java中规定,在JDK8之后,接口中可以一定静态方法,但是这个静态方法,只能通过“该接口名”去调用的。别的都无法调用。 * 在JDK8之后引入接口可以定义静态方法,实际上想表达一个意思:接口也可以作为工具来使用了。 * 10.JDK9之后允许接口中定义私有的实例方法(为默认方法服务的)和私有的静态方法(为静态方法服务的) * * * **/ public interface MyInterface { public static final int number = 1; //3.抽象类是半抽象的,接口是完全抽象的。接口没有构造方法,也无法实例化。 //3.void m2(){}; 错误写法,不能有方法体。 void m2(); //4. public abstract 可以省略 public abstract void m1(); //9.默认方法 default void defaultMethod(){ System.out.println("接口中的默认方法defaultMethod执行了"); } // 10.JDK9之后允许定义私有的静态方法。(给静态方法服务的) static void staticMethod(){ System.out.println("接口的静态方法执行了"); } } interface A{ void a(); } interface B{ void b(); } //5.接口直接可以多继承 interface C extends A,B{ void c(); } //6.类和接口的关系我们叫做实现(这里的实现也可以等同看做继承)。使用implements关键字进行接口的实现。 class MyInterfaceImpl implements MyInterface,C{ @Override public void c() { System.out.println("c执行了"); } @Override public void a() { System.out.println("a执行了"); } @Override public void b() { System.out.println("b执行了"); } @Override public void m2() { System.out.println("m2执行了"); } @Override public void m1() { System.out.println("m1执行了"); } }
主程序:
package com.baidu.com.jia.jiekou; public class MyInterfaceTest { public static void main(String[] args) { //这只是一个变量,是一个引用。 //使用接口类型也可以定义引用。 MyInterface myInterface = null ; //没有使用多态机制 // MyInterfaceImpl mii = new MyInterfaceImpl(); // mii.a(); // mii.b(); // mii.c(); // mii.m1(); // mii.m2(); // 使用了接口之后,为了降低程序的耦合度:一定要让接口和多态联合起来。 //父类型引用执行子类型对象。 MyInterface mi = new MyInterfaceImpl(); mi.m1(); mi.m2(); mi.defaultMethod(); } }
3.接口的作用 (有无接口区别)
3.1实例代码
3.1.1无接口代码
假如说电脑要连打印机,在定义一个新的类,这部分符合OCP(可扩展原则),但是Computer电脑类的源码改变,不符合OCP原则。
这个程序没有使用接口。分析存在哪些缺点?
违背OCP 开闭原则。
Computer类的扩展力差
为什么?
Computer类中使用了HardDriver类,以及Printer类导致Computer类和HardDrive,Printer合度太高Computer类扩展力太差。
public class Computer {
//连接方法
public void conn(HardDrive hardDrive){
System.out.println("连接设备成功");
hardDrive.read();
hardDrive.write();
}
}
public class HardDrive {
public void read(){
System.out.println("硬盘开始读数据");
}
public void write(){
System.out.println("硬盘开始写数据");
}
}
public class Test {
public static void main(String[] args) {
HardDrive hardDrive = new HardDrive();
Computer computer = new Computer();
computer.conn(hardDrive);
}
}
3.1.2接口代码
Computer是调用者,剩下的是实现者,分清调用者和实现者,定义接口,
public void conn(Usb usb){
System.out.println("连接设备成功");
usb.read();
usb.write();
}本质上是用的多态:
Usb usb = new HardDrive();
public class Computer {
//连接方法
public void conn(Usb usb){
System.out.println("连接设备成功");
usb.read();
usb.write();
}
}
public class Printer implements Usb {
public void read(){
System.out.println("打印机开始读数据");
}
public void write(){
System.out.println("打印机开始打印了");
}
}
public class HardDrive implements Usb {
public void read(){
System.out.println("硬盘开始读数据");
}
public void write(){
System.out.println("硬盘开始写数据");
}
}
//主程序
public class Test {
public static void main(String[] args) {
HardDrive hardDrive = new HardDrive();
Printer printer = new Printer();
Computer computer = new Computer();
computer.conn(hardDrive);
computer.conn(printer);
}
}
3.1.3例子代码
//接口
public interface Menu {
void XiHongShiChaoDan();
void YuXiangRouSi();
void GongBaoJiDian();
}
//厨师一和厨师二
public class Cooker implements Menu{
private String name;
public Cooker(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void XiHongShiChaoDan() {
System.out.println("西红柿炒蛋做好了");
}
@Override
public void YuXiangRouSi() {
System.out.println("鱼香肉丝做好了");
}
@Override
public void GongBaoJiDian() {
System.out.println("宫保鸡丁做好了");
}
}
public class Cooker2 implements Menu{
private String name;
public Cooker2(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void XiHongShiChaoDan() {
System.out.println("2西红柿炒蛋做好了");
}
@Override
public void YuXiangRouSi() {
System.out.println("2鱼香肉丝做好了");
}
@Override
public void GongBaoJiDian() {
System.out.println("2宫保鸡丁做好了");
}
}
//顾客
package com.baidu.com.jia.jiekoushili;
/**
* 顾客面向菜单点菜
* */
public class Customer {
public void order(Menu menu){
//调用的都是接口中的方法,面向接口编程,面向抽象编程,降低程序耦合度,提高程序扩展力
menu.GongBaoJiDian();
menu.XiHongShiChaoDan();
menu.YuXiangRouSi();
}
}
//主程序
package com.baidu.com.jia.jiekoushili;
public class Test {
public static void main(String[] args) {
Cooker cooker = new Cooker("山东厨师");
Customer customer = new Customer();
Cooker2 cooker2 = new Cooker2("陕西厨师");
customer.order(cooker);
}
}
接口与抽象类如何选择