Java 接口
文章目录
- [Java 接口](#Java 接口)
- 补充
-
- [面向对象 七大设计原则](#面向对象 七大设计原则)
1.接口的语法
接口:相当于特殊的抽象类,定义方式、组成部分与抽象类类似。
eg:
md
特点:
使用interface关键字定义接口
没有构造方法,不能创建对象
只能定义:公开静态常量、公开抽象方法
java
// JDK 1.8 之前
public interface Myinterface {
public static final int COUNt = 100;
public abstract void method();
}
/* 可以省略 'public', 'static', 'final', 'abstract' 关键字
Modifier 'public' is redundant for interface members
Modifier 'static' is redundant for interface fields
Modifier 'final' is redundant for interface fields
Modifier 'abstract' is redundant for interface methods
*/
//JDK 1.8 之后
JDK 1.8 版本接口中可以包含公开静态方法和公开默认方法
- 公开静态方法:不能被继承,通过接口名.方法名调用
static void method() {...}
- 公开默认方法:可以被继承,也可以被重写,通过实现类调用
default void method() {...} //default 不是访问权限修饰符, 仅表示 "默认"
1.1 与抽象类的区别
相同:
- 可编译成字节码文件。
- 不能创建对象。
- 都可以声明变量(引用)。
- 隐式具备Object类中所定义的方法。
不同:
- 接口所有属性都是公开静态常量,隐式使用public static final修饰。
- 接口所有方法都是公开抽象方法,隐式使用public abstract修饰。
- 接口没有构造方法、动态代码块、静态代码块。
- 抽象类没有限制。
2.如何使用接口?
同抽象类相似, 都需要一个类去实现它; 使用 implement 关键字实现;
eg:
md
如何使用接口
接口:
java
public interface MyInterface {
int COUNt = 100;
void method();
}
实现类:
java
public class Student implements MyInterface{
@Override
public void method() {
System.out.println("实现接口中的方法");
}
}
测试类:
java
public class Test {
public static void main(String[] args) {
//使用声明引用
Student student = new Student();
//调用方法
student.method();
//调用常量
System.out.println(Student.COUNt);
}
}
2.1 接口的使用规范
-
任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
-
实现接口中的抽象方法时,访问修饰符必须是public。
-
同父类一样,接口可声明为引用,并指向实现类对象。
-
仅可调用接口中所声明的方法,不可调用实现类中独有的方法。
-
可强转回实现类本身类型,进行独有方法调用。
-
3.什么是接口?
宏观概念:接口是一种标准。
微观概念:接口是一种能力和约定。
- 接口的定义:代表了某种能力。
- 方法的定义:能力的具体要求。
经验:Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。
接口支持多实现,可为类扩充多种能力。
3.1 常见关系
- 类与类 : extends
- 单继承
- extends 父类名称
- 类与接口 : implement
- 多实现
- implements 接口名称1 , 接口名称2 , 接口名称n
- 继承和实现同时存在时,继承在前,实现在后
- 接口与接口 :
- 多继承
- extends 父接口1 , 父接口2 , 父接口n
4.接口的多态性
内存图:
特点:(微观概念) 接口是一种能力和约定。
不同引用类型,仅可调用自身类型中所声明的方法。
eg:
md
编写代码, 体现接口是一种能力和约定,以及接口的多态性
Animal:
java
public abstract class Animal {
String breed;
int age;
String gender;
public abstract void eat();
public abstract void sleep();
public abstract void show();
}
Runnable:
java
public interface Runnable {
void run();
}
Swimmable:
java
public interface Swimmable {
void swim();
}
Dog:
java
public class Dog extends Animal implements Runnable, Swimmable{
String color;
@Override
public void eat() {
System.out.println("狗狗啃骨头...");
}
@Override
public void sleep() {
System.out.println("狗狗睡觉...");
}
@Override
public void show() {
System.out.println("狗狗信息...");
}
@Override
public void run() {
System.out.println("狗狗奔跑...");
}
@Override
public void swim() {
System.out.println("狗狗游泳...");
}
public void shout() {
System.out.println("狗狗开始狗叫...");
}
}
Test:
java
public class Test {
public static void main(String[] args) {
//创建狗狗对象
//把狗狗当作狗看
Dog dog = new Dog();
dog.eat();
dog.sleep();
dog.show();
dog.run();
dog.swim();
dog.shout();
//多态: 把狗狗当作Animal看
Animal animal = dog;
animal.eat();
animal.sleep();
animal.show();
//多态: 把狗狗当作能跑的对象看
Runnable runnable = dog;
runnable.run();
//多态: 把狗狗当作能游泳的对象看
Swimmable swimmable = dog;
swimmable.swim();
}
}
5.面向接口编程
特点:(宏观概念) 接口是一种标准。
面向接口编程,而非面向实现类 (依赖倒置原则)
eg:
md
用代码实现: 电脑具有USB接口, 连接带USB接口的设备
Usb:
java
public interface Usb {
void service();
}
Fan:
java
public class Fan implements Usb{
@Override
public void service() {
System.out.println("风扇开始工作, 降温....");
}
}
Mouse:
java
public class Mouse implements Usb{
@Override
public void service() {
System.out.println("鼠标开始工作, 移动...");
}
}
Computer:
java
public class Computer {
public Usb usb1, usb2;
public void work() {
System.out.println("电脑开始工作...");
if (usb1 != null) {
//实现者 交给 接口的使用者 调用
usb1.service();
}
if (usb2 != null) {
usb2.service();
}
}
}
Test:
java
public class Test {
public static void main(String[] args) {
Computer Leven = new Computer();
Mouse mouse = new Mouse();
Fan fan = new Fan();
//连接电脑
Leven.usb1 = mouse;
Leven.usb2 = fan;
Leven.work();
}
}
5.1 接口回调
使编程符合现实逻辑
接口回调:先有接口的使用者,后有接口的实现者; 实现者交给接口的使用者调用
先有电脑, 再有鼠标, 鼠标需要交给电脑来使用
没有电脑, 光有鼠标, 逻辑上没法使用鼠标的功能
6.特殊接口
6.1 常量接口
常量接口: 将多个常用于表示状态或固定值的变量,以静态常量的形式定义在接口中统一管理,提高代码可读性。
eg:
java
public interface Week {
//静态常量
String MONDAY = "星期一";
String TUESDAY = "星期二";
String WEDNESDAY = "星期三";
String THURSDAY = "星期四";
String FRIDAY = "星期五";
String SATURDAY = "星期六";
String SUNDAY = "星期日";
}
6.2 标记接口
标记接口 : 接口没有任何成员,仅仅是一个标记。Serializable 、Cloneable
7.接口的好处
- 降低程序的耦合性,更自然的使用多态。
- 设计与实现完全分离,更容易搭建程序框架,更换具体实现。
补充
面向对象 七大设计原则
总则:开闭原则(Open Close Principle,OCP)
- 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。
单一职责原则(Single Responsibility Principle,SRP)
- 不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。
里氏替换原则(Liskov Substitution Principle,LSP)
- 里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现。
- 里氏替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。
依赖倒置原则(Dependence Inversion Principle,DIP)
- 面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。
接口隔离原则(Interface Segregation Principle,ISP)
- 每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
迪米特法则(最少知道原则)(Demeter Principle,DP)
- 一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
- 只和朋友通信,不和陌生人说话。
合成/聚合复用原则(Composite Reuse Principle,CRP)
- 原则是尽量首先使用合成/聚合的方式,而不是使用继承。