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

 

 

 

 

 

posted @ 2013-04-12 15:00  谷文仁  阅读(169)  评论(0编辑  收藏  举报