• Java_接口


    3.9、接口(重点)

    3.9.1 、接口的基本概念

             接口属于一种特殊的类,如果一个类定义的时候全部由抽象方法和全局常量所组成的话,那么这种类就称为接口,但是接口是使用interface关键字进行定义的。

    interface A {        // 定义接口

             public static final String INFO = "Hello World ." ;

             public abstract void print() ;

    }

    interface B {

             public abstract void get() ;

    }

             那么在接口之中,也同样存在了抽象方法,很明显,接口对象无法直接进行对象的实例化操作,那么接口的使用原则如下:

             · 每一个接口必须定义子类,子类使用implements关键字实现接口;

             · 接口的子类(如果不是抽象类)则必须覆写接口之中所定义的全部抽象方法;

             · 利用接口的子类,采用对象的向上转型方式,进行接口对象的实例化操作。

             下面给出子类实现接口的语法格式:

    class 子类 [extends 父类] [implemetns 接口1,接口2,...] {}

             通过格式可以发现,每一个子类可以同时实现多个接口,但是只能继承一个父类。

    范例:让子类实现接口

    interface A {        // 定义接口

             public static final String INFO = "Hello World ." ;

             public abstract void print() ;

    }

    interface B {

             public abstract void get() ;

    }

    class X implements A,B {    // 同时实现了两个接口

             public void print() {      // 方法覆写

                       System.out.println("Hello World .") ;

             }

             public void get() {

                       System.out.println(INFO) ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       A a = new X() ;

                       B b = new X() ;

                       a.print() ;

                       b.get() ;

             }

    }

             那么如果一个类现在即要实现接口又要继承抽象类的话,则应该采用先继承后实现的方式完成。

    interface A {        // 定义接口

             public static final String INFO = "Hello World ." ;

             public abstract void print() ;

    }

    interface B {

             public abstract void get() ;

    }

    abstract class C {

             public abstract void fun() ;

    }

    class X extends C implements A,B {        // 同时实现了两个接口

             public void print() {      // 方法覆写

                       System.out.println("Hello World .") ;

             }

             public void get() {

                       System.out.println(INFO) ;

             }

             public void fun() {

                       System.out.println("世界,你好!") ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       A a = new X() ;

                       B b = new X() ;

                       C c = new X() ;

                       a.print() ;

                       b.get() ;

                       c.fun() ;

             }

    }

             但是需要说明的是:接口之中的全部组成就是抽象方法和全局常量,那么在开发之中以下的两种定义接口的最终效果是完全一样的:

    完整定义:

    简化定义:

    interface A {       // 定义接口

             public static final String INFO = "Hello World ." ;

             public abstract void print() ;

    }

    interface A {       // 定义接口

             public String INFO = "Hello World ." ;

             public void print() ;

    }

             接口之中的访问权限只有一种:public,即:定义接口方法的时候就算没有写上public,那么最终也是public

             在Java之中每一个抽象类都可以实现多个接口,但是反过来讲,一个接口却不能继承抽象类,可是Java之中,一个接口却可以同时继承多个接口,以实现接口的多继承操作。

    interface A {

             public void printA() ;

    }

    interface B {

             public void printB() ;

    }

    interface C extends A,B {     // 一个接口继承了多个接口

             public void printC() ;

    }

    class X implements C {

             public void printA() {}

             public void printB() {}

             public void printC() {}

    }

             而在开发之中,内部类是永远不会受到概念限制的,在一个类中可以定义内部类,在一个抽象类之中也可以定义抽象内部类,在一个接口里面也可以定义内部抽象类或内部接口,但是从实际的开发来讲,用户自己去定义内部抽象类或内部接口的时候是比较少见的(Android开发中见过内部接口),而且在定义内部接口的时候如果使用了static,表示是一个外部接口

    interface A {

             public void printA() ;

             static interface B {        // 外部接口

                       public void printB() ;

             }

    }

    class X implements A.B {

             public void printB() {

                       System.out.println("Hello World .") ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       A.B temp = new X() ;

                       temp.printB() ;

             }

    }

             以上对于接口的概念并不是很难理解,但是需要强调的是,在实际的开发之中,接口有三大主要功能:

                       ·制订操作标准;

                       ·表示一种能力;

                       ·将服务器端的远程方法视图暴露给客户端。

    3.9.2 、使用接口定义标准

             在日常的生活之中,接口这一名词经常听到的,例如:USB接口、打印接口、充电接口等等。

             现在假设每一个USB设备只有两个功能:安装驱动程序、工作。

    范例:定义出一个USB的标准

    interface USB {   // 操作标准       

             public void install() ;

             public void work() ;

    }

    范例:在电脑上应用此接口

    class Computer {

             public void plugin(USB usb) {

                       usb.install() ;

                       usb.work() ;

             }

    }

    范例:定义USB设备

    class Phone implements USB {

             public void install() {

                       System.out.println("安装手机驱动程序。") ;

             }

             public void work() {

                       System.out.println("手机与电脑进行工作。") ;

             }

    }

    范例:定义USB设备

    class Print implements USB {

             public void install() {

                       System.out.println("安装打印机驱动程序。") ;

             }

             public void work() {

                       System.out.println("进行文件打印。") ;

             }

    }

    范例:连接

    interface USB {   // 操作标准       

             public void install() ;

             public void work() ;

    }

    class Computer {

             public void plugin(USB usb) {

                       usb.install() ;

                       usb.work() ;

             }

    }

    class Phone implements USB {

             public void install() {

                       System.out.println("安装手机驱动程序。") ;

             }

             public void work() {

                       System.out.println("手机与电脑进行工作。") ;

             }

    }

    class Print implements USB {

             public void install() {

                       System.out.println("安装打印机驱动程序。") ;

             }

             public void work() {

                       System.out.println("进行文件打印。") ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Computer c = new Computer() ;

                       c.plugin(new Phone()) ;         // USB usb = new Phone() ;

                       c.plugin(new Print()) ;

             }

    }

             按照这种方式开发下去的话,不管有多少个USB接口的子类,都可以在电脑上使用。

    3.9.3 、接口的实际作用 —— 工厂设计模式(Factory)

             下面首先来观察如下的程序代码。

    interface Fruit {

             public void eat() ;

    }

    class Apple implements Fruit {

             public void eat() {

                       System.out.println("吃苹果。") ;

             }

    }

    class Orange implements Fruit {

             public void eat() {

                       System.out.println("吃橘子。") ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Fruit f = new Apple() ;

                       f.eat() ;

             }

    }

             本程序非常简单就是通过接口的子类为接口对象实例化,但是本操作存在什么样的问题呢?

             之前一直在强调,主方法或者是主类是一个客户端,客户端的操作应该越简单越好。但是现在的程序之中,有一个最大的问题:客户端之中,一个接口和一个固定的子类绑在一起了。

             在本程序之中,最大的问题在于耦合上,发现在主方法之中,一个接口和一个子类紧密耦合在一起,这种方式比较直接,可以简单的理解为由:A è B,但是这种紧密的方式不方便于维护,所以后来使用了A è C è B,中间经历了一个过渡,这样一来B去改变,C去改变,但是A不需要改变,就好比JAVA的JVM一样:程序 è JVM è 操作系统。

    范例:修改代码

    interface Fruit {

             public void eat() ;

    }

    class Apple implements Fruit {

             public void eat() {

                       System.out.println("吃苹果。") ;

             }

    }

    class Orange implements Fruit {

             public void eat() {

                       System.out.println("吃橘子。") ;

             }

    }

    class Factory {

             public static Fruit getInstance(String className) {

                       if ("apple".equals(className)) {

                                return new Apple() ;

                       }

                       if ("orange".equals(className)) {

                                return new Orange () ;

                       }

                       return null ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Fruit f = Factory.getInstance(args[0]) ;

                       f.eat() ;

             }

    }

             这个时候发现客户端不再和一个具体的子类耦合在一起了,就算以后增加了新的子类,那么只需要修改Factory类即可实现。

    3.9.4 、接口的实际作用 —— 代理设计模式(Proxy)

             张金宇的不幸人生。。。555555。

    interface Subject {        // 操作主题

             public void get() ;         // 要银子

    }

    class RealSubject implements Subject {   // 真正的要银子

             public void get() {

                       System.out.println("真实业务主题") ;

             }

    }

    class ProxySubject implements Subject {

             private Subject sub = null ;

             public ProxySubject(Subject sub) {

                       this.sub = sub ;

             }

             public void prepare() {

                       System.out.println("准备操作。") ;

             }

             public void destroy() {

                       System.out.println("收尾操作。") ;

             }

             public void get() {

                       this.prepare() ;

                       this.sub.get() ;

                       this.destroy() ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Subject sub = new ProxySubject(new RealSubject()) ;

                       sub.get() ;

             }

    }

             通过以上的分析就可以得出结论:代理负责完成与真实业务有关的所有辅助性操作。

    3.9.5 、抽象类和接口的区别(面试题)

             通过如上的分析,感觉抽象类和接口在使用上似乎区别不大,那么下面就通过一个表格给出这两者的区别。

    (面试题:请解释抽象类和接口的区别?)

    No.

    区别

    抽象类

    接口

    1

    定义关键字

    abstract class

    interface

    2

    组成

    常量、变量、抽象方法、普通方法、构造方法

    全局常量、抽象方法

    3

    权限

    可以使用各种权限

    只能是public

    4

    关系

    一个抽象类可以实现多个接口

    接口不能够继承抽象类,却可以继承多接口

    5

    使用

    子类使用extends继承抽象类

    子类使用implements实现接口

    抽象类和接口的对象都是利用对象多态性的向上转型,进行接口或抽象类的实例化操作

    6

    设计模式

    模板设计模式

    工厂设计模式、代理设计模式

    7

    局限

    一个子类只能够继承一个抽象类

    一个子类可以实现多个接口

             通过上面的分析可以得出结论:在开发之中,抽象类和接口实际上都是可以使用的,并且使用那一个都没有明确的限制,可是抽象类有一个最大的缺点 —— 一个子类只能够继承一个抽象类,存在单继承的局限,所以当遇到抽象类和接口都可以使用的情况下,优先考虑接口,避免单继承局限

             到此时已经学习过了:对象、类、抽象类、接口、继承、实现等等,这些都属于什么样的关系呢?

             接口就是在类的基础之上的进一步具体的抽象。

    4、总结

    1、   继承性用于扩充类的功能;

    2、   方法的覆写与对象多态性的联系;

    3、   final关键字的使用;

    4、   单例设计模式;

    5、   对象的多态性,转型问题;

    6、   抽象类和接口的概念;

    7、   今天的三个设计模式(背下结构):单例、工厂、代理。

    5、预习任务

             匿名内部类、Object类、异常的捕获及处理、包及访问控制权限。

    6、作业

    No.

    表达式

    描述

    1

     

    2

     

    3

     

    4

     

    5

     

    6

     

    7

     

    8

     

    9

     

    No.

    方法名称

    类型

    描述

    1

     

     

    2

     

     

    3

     

     

    4

     

     

    5

     

     

    6

     

     

    7

     

     

    8

     

     

    9

     

     

  • 相关阅读:
    Django 常见问题
    post和get的区别
    Django 基础学习笔记二
    Django 中的分页器
    Python 微服务框架 Nameko 微服务通信(RabbitMQ)
    《大数据白皮书 2020.12》解读
    练习Div+Css
    利用JAVAScript调用WebService
    统计在线人数和历史访问人数
    自己写的一个DBHelper
  • 原文地址:https://www.cnblogs.com/guwenren/p/3016695.html
Copyright © 2020-2023  润新知