Java 接口——面向对象的精髓

来源:互联网 发布:北大青鸟crt软件下载 编辑:程序博客网 时间:2024/06/16 07:50

接口有何用?面试宝典上背下来的总结,你真的明白吗?

接口&工厂方法 其实很简单>。<~

什么是接口

先看看生活中的接口,比如USB接口。

USB接口的设计者在最初就知道USB能支持这么多功能吗?他们是怎

样未卜先知地设计的呢?其实他们也不知道以后USB上会连什么设

备,他们只是定义了一个数据传输与供电的标准而已。

Java中也是类似的,定义了接口,就等于定义了调用对象的标准。

接口的基本语法

使用 interface定义;

接口当中的方法都是抽象方法;

接口当中的方法都是public权限(接口中的方法,写不写public修饰

符,都是public权限,别的地方不行哦);

可以把接口理解成一个更加纯粹的抽象类,因此它也不能生成对象。

这要怎么办呢?回想抽象类的处理方法,可以用一个类来继承(接口

中叫实现)它,从而在子类中生成对象。

一个最简单的接口示例:

定义一个接口:

interface USB {    public void read();        public void write();}

定义它的子类,来实现这个接口:

class Phone implements USB {    public void read() {        System.out.println("Phone --> Read");    }        public void write() {        System.out.println("Phone --> Write");    }}

测试:

class Test {    public static void main(String args []) {        Phone phone = new Phone();        //向上转型        USB usb = phone;        usb.read();        usb.write();    }}

运行结果:
图片描述
继续了解接口的语法:

实现接口使用implements关键字;

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

实现是特殊的继承,换句话说,就是一个类可以继承多个接口。

修改上面的代码:
再定义一个WiFi接口:

interface WiFi {    public void open();        public void close();}

让Phone也实现WiFi接口:

class Phone implements USB, WiFi {    public void read() {        System.out.println("Phone --> Reading");    }        public void write() {        System.out.println("Phone --> Writing");    }    //实现WiFi中的抽象方法    public void open() {        System.out.println("WiFi --> Open");    }        public void close() {        System.out.println("WiFi --> Close");    }    }

测试一下:

class Test {    public static void main(String args []) {        Phone phone = new Phone();        //向上转型时,就有两种选择        USB usb = phone;        usb.read();        usb.write();        WiFi wifi = phone;        wifi.open();        wifi.close();    }}

运行结果:
图片描述

可以看到,用USB连接手机时,手机表现的就是USB的行为,用WiFi

连接手机时,手机表现的就是WiFi的行为,这也是面向对象多态性非

常明显的体现。

一个接口可以继承多个接口

注意这里不能写成implements,因为我们只想继承USB和WiFi接口

的抽象方法,而不想实现它。

interface SbFi extends USB, WiFi {  public void piu();}

这样SbFi接口就拥有read(),write(),open(),close()和piu()五个抽象方法了:)
接口的实践

如果我们接到一个客户的需求,用程序控制办公室中的打印机,我们

该怎么做呢?容易想到,先用一个类描述“打印机”,再用一些方法

实现“开机”、“关机”、“打印”等动作,一个简单的Printer类就能搞定了。
可是如果客户提出了新的需求,办公室又买了一台其他品牌的打印

机,让你修改之前的代码。这时要怎么做呢?都是打印机,只是品牌

不同,功能略有差异,容易想到用接口或者继承。接口更灵活一些,

所以我们写出了下面的代码:

首先定义一个Printer接口,描述打印机都有的行为:

interface Printer {    void open();    void print(String s);    void close();}

在惠普打印机类中,实现Printer中的抽象方法:

class HPPrinter implements Printer {    public void open() {        System.out.println("HP: open");    }    public void print(String s) {        System.out.println("HP: print--> " + s);    }    public void close() {        System.out.println("HP: close");    }}

在佳能打印机中,又增加了新的方法,清洗:

public class CanonPrinter implements Printer {    public void open() {        System.out.println("Canon: open");    }    public void print(String s) {        System.out.println("Canon: print-->" + s);    }    public void close() {        this.clean();        System.out.println("Canon: close");    }    public void clean() {        System.out.println("Canon: clean");    }}

测试:
注意,这里使用对象的向上转型,能减少重复代码。不然就得用

HPPrinter和CanonPrinter生成的对象分别调用open, print, close方

法,很麻烦。如果以后有100台打印机,岂不是得写300行?

class Test {    public static void main(String args []) {        Printer printer = null;        //为简便,flag模拟用户选择使用哪台打印机        int flag = 1;        if(flag == 0) {            //向上转型            printer = new HPPrinter();        } else if(flag == 1) {            printer = new CanonPrinter();        }        printer.open();        printer.print("向上转型好用吧~");        printer.close();    }}

运行:
图片描述

大功告成。但是这样就足够了吗?

如果我们的打印机代码,是在一个办公自动化的系统当中。可能有各

种各样的功能,要使用打印机。那每次使用时,都要把Test类中的这

一段写一遍吗?如果以后有100个地方要用,岂不是要把这一段写

100次?更可怕的是,如果又添加了新的打印机,岂不是要修改这

100段代码?太容易出错了。所以,我们和重复代码,是势不两立的

(振臂一呼)!

进击的工厂方法模式

减少重复代码的一般方法就是,把重复的代码放在一个地方(封装起

来),等要用的时候,就调用它,而不是再写一遍。仔细看Test类,

重复的地方,不包括最后三行,主要是根据用户的选择,生成打印机

对象,并向上转型为Printer类型的部分。

我们可以设计一个类,在里面添加一个函数,它的功能就是根据用户

的选择生成打印机对象,以后我们直接调用这个函数就行了。函数的

参数,就是用户的选择,返回值,就是一个Printer类型的对象。

class PrinterFactory {    //添加static是为了调用方便    public static Printer getPrinter(int flag) {        Printer printer = null;        if(flag == 0) {            printer = new HPPrinter();        } else if(flag == 1) {            printer = new CanonPrinter();        }                return printer;    }    }class Test {    public static void main(String args []) {        int flag = 1;        Printer printer = PrinterFactory.getPrinter(flag);        printer.open();        printer.print("对象的转型好用吧~");        printer.close();    }}

这样,就算要增加100台打印机,也只用在PrinterFactory中添加

else if(flag == xxx) 的代码,不用修改Test类。

这就是著名的简单静态工厂方法模式。

PrinterFactory并不关心Printer类有多少个子类,这样我们就能够自由地修改Printer子类了。

工厂方法模式的思路很简单,就是把生成对象的代码,封装在工厂类当中。

0 0
原创粉丝点击