Java 基础(接口)
接口详解一
- 一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java 不支持多重继承。有了接口,就可以得到多重继承的效果
- 另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。
- 接口就是规范,定义的是一组规则,体现了现实世界中 "如果你是/要...则必须能..." 的思想。继承是一个"是不是"的关系,而接口实现则是"能不能"的关系。
- 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。
接口的使用
- 接口使用 interface 来定义
- Java 中,接口和类是并列的两个结构
- 如何定义接口: 定义接口中的成员
3.1 JDK7 及以前: 只能定义全局常量和抽象方法
> 全局常量: public static final 的
> 抽象方法: public abstract 的
3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略) - 接口中不能定义构造器! 意味着接口不可以实例化
- Java开发中,接口通过让类去实现(implements)的方式来使用
如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类 - Java 类可以实现多个接口 ---> 弥补了 Java 单继承性的局限性
格式: class AA extends BB implements CC,DD,EE - 接口与接口之间可以继承,而且可以多继承
- 接口的具体使用,体现多态性
- 接口,实际上可以看做是一种规范
InterfaceTest.java
package com.klvchen.java1; public class InterfaceTest { public static void main(String[] args) { System.out.println(Flyable.MAX_SPEED); System.out.println(Flyable.MIN_SPEED); // Flyable.MIN_SPEED = 2; Plane plane = new Plane(); plane.fly(); } } interface Flyable{ //全局常量 public static final int MAX_SPEED = 7900; //第一宇宙速度 int MIN_SPEED = 1; //省略了 public static final //抽象方法 public abstract void fly(); //省略了 public abstract void stop(); } interface Attackable{ void attack(); } class Plane implements Flyable{ @Override public void fly() { System.out.println("通过引擎起飞"); } @Override public void stop() { System.out.println("驾驶员减速停止"); } } abstract class Kite implements Flyable{ @Override public void fly() { // TODO Auto-generated method stub } } class Bullet extends Object implements Flyable, Attackable{ @Override public void attack() { // TODO Auto-generated method stub } @Override public void fly() { // TODO Auto-generated method stub } @Override public void stop() { // TODO Auto-generated method stub } }

接口详解二
- 定义Java类的语法格式: 先写 extends,后写 implements
- class SubClass extends SuperClass implements InterfaceA{}
- 一个类可以实现多个接口,接口也可以继承其它接口。
- 实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
- 接口的主要用途就是被实现类实现。((面向接口编程)
- 与继承关系类似,接口与实现类之间存在多态性
- 接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义(JDK7.0及之前),而没有变量和方法的实现。
USBTest.java
package com.klvchen.java1; public class USBTest { public static void main(String[] args) { Computer com = new Computer(); //1. 创建了接口的非匿名实现类的非匿名对象 Flash flash = new Flash(); com.transferData(flash); System.out.println("******************************"); //2. 创建了接口的非匿名实现类的匿名对象 com.transferData(new Printer()); System.out.println("******************************"); //3. 创建了接口的匿名实现类的非匿名对象 USB phone = new USB() { @Override public void start() { System.out.println("手机开始工作"); } @Override public void stop() { System.out.println("手机结束工作"); } }; com.transferData(phone); System.out.println("******************************"); //4. 创建了接口的匿名实现类的匿名对象 com.transferData(new USB() { @Override public void start() { System.out.println("MP3开始工作"); } @Override public void stop() { System.out.println("MP3结束工作"); } }); } } class Computer{ public void transferData(USB usb) { usb.start(); System.out.println("具体传输数据的细节"); usb.stop(); } } interface USB{ //常量: 定义了长,宽,高,最大最小的传输速度等 void start(); void stop(); } class Flash implements USB{ @Override public void start() { System.out.println("U盘开启工作"); } @Override public void stop() { System.out.println("U盘结束工作"); } } class Printer implements USB{ @Override public void start() { System.out.println("打印机开启工作"); } @Override public void stop() { System.out.println("打印机结束工作"); } }

Java8中关于接口的改进
Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像 Collection/Collections 或者 Path/Paths 这样成对的接口和类。
默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。比如: java 8 API 中对 Collection、List、Comparator 等接口提供了丰富的默认方法。
CompareA.java
package com.klvchen.java8; /* * JDK8, 除了定义全局常量和抽象方法之外,还可以定义静态方法,默认方法 * * */ public interface CompareA { //静态方法 public static void method1() { System.out.println("CompareA:北京"); } //默认方法 public default void method2() { System.out.println("CompareA public default:上海"); } default void method3() { System.out.println("CompareA default:上海"); } }
CompareB.java
package com.klvchen.java8; public interface CompareB { default void method3() { System.out.println("CompareB: 上海"); } }
SuperClass.java
package com.klvchen.java8; public class SuperClass { public void method3() { System.out.println("SuperClass: 北京"); } }
SubClassTest.java
package com.klvchen.java8; public class SubClassTest { public static void main(String[] args) { SubClass s = new SubClass(); // s.method1(); // SubClass.method1(); //知识点1:接口中定义的静态方法,只能通过接口来调用。 CompareA.method1(); //知识点2:通过实现类的对象,可以调用接口中的默认方法 //如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法 s.method2(); //知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法, //那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。 --> 类优先原则 //知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法, //那么在实现类没有重写此方法的情况下,报错。-->接口冲突。 //这就需要我们必须在实现类中重写此方法 s.method3(); // SubClass.method2(); System.out.println("*******************************"); s.myMethod(); } } class SubClass extends SuperClass implements CompareA, CompareB{ //class SubClass implements CompareA, CompareB{ public void method2() { System.out.println("SubClass: 上海"); } public void method3() { System.out.println("SubClass: 深圳"); } public void myMethod() { method3(); //调用自己定义的重写的方法 super.method3(); //调用的是父类中声明的 //调用接口中的默认方法 CompareA.super.method3(); CompareB.super.method3(); } }

Man.java
package com.klvchen.java8; interface Filial { default void help() { System.out.println("Lily,我来救你了"); } } interface Spoony{ default void help() { System.out.println("Lucy, 我来救你了"); } } class Father{ public void help() { System.out.println("救Lucy"); } } public class Man extends Father implements Filial, Spoony { @Override public void help() { System.out.println("我改救谁呢?"); Filial.super.help(); Spoony.super.help(); } public static void main(String[] args) { Man m = new Man(); m.help(); } }


浙公网安备 33010602011771号