11.1 接口语法
11.1.1 基本使用
概念:接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似。使用interface关键字定义接口。
特点:
- 没有构造方法,不能创建对象。
- 只能定义:公开静态常量、公开抽象方法。
案例演示:自定义接口。
public interface MyInterface { //接口中:只能定义公开的静态常量和公开抽象方法 // 没有构造方法、动态、静态代码块 public static final int a = 10; public abstract void show(); }
11.1.2 和抽象类区别
相同点:
- 可编译成字节码文件。
- 不能创建对象。
- 可以作为引用类型。
- 具备Object类中所定义的方法。
不同点:
- 所有属性都是公开静态常量,隐式使用public static final修饰。
- 所有方法都是公开抽象方法,隐式使用public abstract修饰。
- 没有构造方法、动态代码块、静态代码块。
11.2 微观接口
微观概念:接口是一种能力和约定。
- 接口的定义:代表了某种能力。
- 方法的定义:能力的具体要求。
经验:
- Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。
- 接口支持多实现,可为类扩充多种能力。
案例演示:实现类实现多个接口。
public interface Flyable { void fly(); }
public interface Fireable { void fire(); }
实现类:Person
public class Person implements Flyable,Fireable{ String name; int age; public Person() { // TODO Auto-generated constructor stub } public Person(String name, int age) { super(); this.name = name; this.age = age; } public void eat() { System.out.println(name+"吃东西..."); } public void sleep() { System.out.println(name+"睡了..."); } @Override public void fly() { System.out.println(name+"开始飞了..."); } @Override public void fire() { System.out.println(name+"可以喷火了..."); } }
测试类:
public class TestPerson1 { public static void main(String[] args) { Person xiaoming=new Person("小明",20); xiaoming.fly(); xiaoming.fire(); } }
11.3 接口规范
- 任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
- 实现接口中的抽象方法时,访问修饰符必须是public。
- 同父类一样,接口也可声明为引用,并指向实现类对象。
public class TestPerson2 { public static void main(String[] args) { Flyable flyable=new Person("小张",22); flyable.fly(); Fireable fireable=new Person("小李", 15); fireable.fire(); } }
11.4 接口实现多态
不同的引用类型,仅可调用自身类型所定义的方法。
案例演示:
public class Test { public static void main(String[] args) { //抽象类作为引用 Animal a = new Dog();//将狗当做动物看 a.eat(); a.sleep(); //接口作为引用 Runnable r = new Dog();//将狗当做能跑的看 r.run(); //接口作为引用 Swimmable s = new Dog();//将狗当做能游泳的看 s.siwm(); Dog dog = new Dog();//将狗当做狗的看 dog.eat(); dog.sleep(); dog.run(); dog.siwm(); } }
11.5 接口常见关系
类与类:
- 单继承
- extends 父类名称
类与接口:
- 多实现
- implements 接口名称1 , 接口名称2 , 接口名称n
- implements 接口名称1 , 接口名称2 , 接口名称n
接口与接口:
- 多继承
- extends 父接口1 , 父接口2 , 父接口n
案例演示:接口多继承。
public interface Runnable extends Serializable ,Cloneable{ //跑 void run(); }
11.6 常量接口
将多个常用于表示状态或固定值的变量,以静态常量的形式定义在接口中统一管理,提高代码可读性。
补充 标记接口接口没有任何成员,仅仅是一个标记。Serializable、Cloneable
public interface Constants { //QQ的状态 接口常量 --- > 枚举类型 public static final int ZAI_XIAN = 100; //在线 public static final int YIN_SHEN = 200; //隐身 public static final int LI_XIAN = 300; //离线 public static final int Q_WO = 400; //Q我 public static final int MANG_LU = 500; //忙碌 }
int num = 100; switch (num) { case Constants.ZAI_XIAN: System.out.println("在线的代码"); break; case Constants.YIN_SHEN: System.out.println("隐身的代码"); break; case Constants.LI_XIAN: System.out.println("离线的代码"); break; default: break; }
11.7 宏观接口
11.7.1 概念
宏观概念:接口是一种标准、规范。
案例演示:
public interface BookInterface { /** * 增删改查 */ public boolean addBook(Book book); public boolean updateBook(Book book); public boolean deleteBook(String bookId); public Book selectOne(String bookId); public Book[] selectAll(); }
public class BookInterfaceImpl implements BookInterface{ @Override public boolean addBook(Book book) { return false; } @Override public boolean updateBook(Book book) { // TODO Auto-generated method stub return false; } @Override public boolean deleteBook(String bookId) { // TODO Auto-generated method stub return false; } @Override public Book selectOne(String bookId) { // TODO Auto-generated method stub return null; } @Override public Book[] selectAll() { // TODO Auto-generated method stub return null; } }
11.7.2 回调原理
接口回调:先有接口的使用者,后有接口的实现者。
(程序员) (接口的使用者)
④工具的调用者---------→→→> ②工具
↓
↓
③接口的实现者 <-←←------------ ①接口
(程序员) (标准)
①接口
//此接口的作用是判断数字是否是质数 interface MyInterface{ boolean isZS(int num); }
②工具
//此方法已经调用了接口中的方法 public static void gdbh(int num,MyInterface mi) { for (int i = 3; i <= num/2; i++) { if(mi.isZS(i) && mi.isZS(num-i)) { System.out.println(num+"="+i+"+"+(num-i)); } } }
③接口的实现者
//这是接口的实现者,在调用工具前,需要有接口的实现 class MyInterfaceImpl implements MyInterface{ @Override public boolean isZS(int num) { for (int i = 2; i < num; i++) { if(num % i == 0) { return false; } } return true; } }
④工具的调用者
public static void main(String[] args) { //使用工具 gdbl(14, new MyInterfaceImpl() ); }
接口回调的编码顺序①②③④
11.7.3 接口好处
- 程序的耦合度降低。
- 更自然的使用多态。
- 设计与实现完全分离。
- 更容易搭建程序框架。
- 更容易更换具体实现。
补充面向对象的七大设计原则
- 总则:开闭原则(Open Close Principle,OCP)
- 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。
2.单一职责原则(Single Responsibility Principle,SRP)
- 不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。
3.里氏替换原则(Liskov Substitution Principle,LSP)
里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现。里氏替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。
4.依赖倒置原则(Dependence Inversion Principle,DIP)
面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。
5.接口隔离原则(Interface Segregation Principle,ISP)
每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
6.迪米特法则(最少知道原则)(Demeter Principle,DP)
一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
只和朋友通信,不和陌生人说话。
7.合成/聚合复用原则(Composite Reuse Principle,CRP)
原则是尽量首先使用合成/聚合的方式,而不是使用继承。
8.开口里合最单依
接口小结:
- 什么是接口:
- 微观:接口是一种能力和约定。
- 宏观:接口是一种标准。
- 接口的特点:
- 没有构造方法,不能创建对象,可以声明变量。
- 只能包含公开静态常量与公开抽象方法。
- 接口的规范
- 任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
- 实现接口中的抽象方法时,访问修饰符必须是public。
- 什么是常量接口、标记接口
- 将多个常用于表示状态或固定值的变量,以静态常量的形式定义在接口中统一管理。
- 什么是接口回调
- 先有接口的使用者,后有接口的实现者。
- 面向对象七大设计原则