10.JAVA-接口、工厂模式、代理模式、详解
2019-05-10 06:05:46来源:博客园 阅读 ()
1.接口定义
接口属于一个特殊的类,这个类里面只能有抽象方法和全局常量 (该概念在JDK1.8之后被打破,在1.8后接口中还可以定义普通方法和静态方法,在后续章节会详讲)
1.1 接口具有以下几个原则
- 接口通过interface关键字来实现定义
- 一个子类如果要继承接口的话,则需要通过implements关键字去实现多个接口(多接口之间通过","隔开),从而实现多继承.
- 接口的子类如果不是个抽象类,则必须要覆写接口的所有抽象方法,才能承认该类实现了这个接口
- 接口的子对象可以通过向上转型进行实例化操作
1.2 接下来来个示例,通过Demo类继承InA和InB两个接口
interface InA //接口InA { public static final String ATTR = "Attribute:InA"; public abstract void PrintA(); } interface InB //接口InB { public static final String ATTR = "Attribute:InB"; public abstract void PrintB(); } class Demo implements InA,InB { public void PrintA() { System.out.println(InA.ATTR); //打印接口A的全局常量 } public void PrintB() { System.out.println(InB.ATTR); //打印接口B的全局常量 } } public class Test{ public static void print(InB b) //接口支持向上转型 { b.PrintB(); } public static void main(String args[]) { Demo d = new Demo(); d.PrintA(); //打印接口A的全局常量 print(d); //等价于d.PrintB(); } }
运行打印:
从上面代码可以看出,接口实际上只是表示一种操作标准 ,而接口本身其实是没有操作能力的,需要子类去实现这个操作能力才行.
2.接口的简化定义
由于接口组成部分是抽象方法和全局常量,所以在方法和常量上写不写public结果都一样,并且方法也可以不用abstract修饰,因为接口里的访问权限都是public的,并且方法默认为抽象的,所以InA接口也可以写为下面这样:
interface InA //接口InA { String ATTR = "Attribute:InA"; //不需要添加public static final void PrintA(); //不需要添加public abstract }
3.接口定义注意的地方
3.1 对于子类或者抽象子类,可以同时继承抽象类以及多个接口,比如:
class Demo extends A implements InA,InB{ // Demo子类继承于A类,以及接口inA和inB //... ... //实现所有抽象方法 }
3.2 对于一个子接口,以通过extends来继承多个父接口,比如:
interface InC extends InA,InB{ //InC子接口继承父接口inA和inB public void funcC(); //定义抽象方法 }
3.3 接口不能继承于抽象类,因为extends关键字用于继承同一品种的(接口!=抽象类),而 implements用于继承于接口的(抽象类!=接口),所以无法实现.
4.接口之工厂设计模式Factory
工厂设计模式,就是说建立一个工厂类,对实现了同一接口的子类们进行统一的实例创建方法,用来提供给用户调用.而用户无需去了解这些对象该如何创建以及如何组织.
4.1工厂设计示例
我们以常用的usb为例,首先需要定义一个USB接口,然后写同一接口的子类们(比如:键盘,鼠标,打印机).由于这些子类们都是独立的,所以我们需要在定义一个工厂类UsbFactory,通过一个方法去统一创建他们,如果不写工厂类的话,假如有100多个USB子类,那岂不是全部创建都要100多个不同的new才行?所以需要一个工厂类负责管理这些对象.
首先定义USB接口和键盘,鼠标子类:
interface USB //USB接口 { public void plugin(); public void out(); } class Keyboard implements USB { public void plugin() { System.out.println("****插上 usb键盘****"); } public void out() { System.out.println("****取出 usb键盘****"); } } class Mouse implements USB { public void plugin() { System.out.println("****插上 usb鼠标****"); } public void out() { System.out.println("****取出 usb鼠标****"); } }
然后定义UsbFactory工厂类:
class UsbFactory { static public USB getInstance(String name) { if("keyboard".equals(name)) //是否为键盘 return new Keyboard(); else if("mouse".equals(name)) //是否为键盘 return new Mouse(); else return null; } }
最后写测试代码:
public class Test{ public static void main(String args[]) { USB usb1 = UsbFactory.getInstance("keyboard"); //获取键盘类 usb1.plugin(); usb1.out(); USB usb2 = UsbFactory.getInstance("mouse"); //获取鼠标类 usb2.plugin(); } }
打印如下:
从上面代码可以看出,通过工厂模式,我们可以更加容易地管理多个相同接口的子类们的操作.
5.代理模式proxy
代理模式,就是说为一个具体对象提供一个代理对象,该代理对象主要是为了封装具体对象,并且完成与具体对象有关的所有操作.而具体对象则只需要负责核心业务.
5.1 代理设计示例
我们以生活中的Eat吃为例,首先需要定义一个Eat接口,然后写一个具体类WhatEat(用来指定具体吃什么),但是在生活中,我们如果吃的不是水果,而是蔬菜,则都要有盘子啊,并且吃之前要先去烧菜盛菜,并且吃完后还要洗碗.而这些操作,我们就不能写在WhatEat类里,因为WhatEat类只负责核心业务(吃),所以便有了代理对象(完成与具体对象有关的所有操作),接下来便写一个EatProxy代理节点类来实现这些与WhatEat类操作.
首先定义Eat接口和具体吃的类(WhatEat):
interface Eat { public int TypeVegetable = 0; //蔬菜 public int TypeFruit = 1; //水果 public void eat(int type); } class WhatEat implements Eat { public void eat(int type) { if(type == Eat.TypeVegetable) System.out.println("*** 吃蔬菜 ***"); else System.out.println("*** 吃水果 ***"); } }
然后定义EatProxy代理节点类:
class EatProxy implements Eat { private Eat eatObject; //代理下的具体对象 public EatProxy(Eat eatObject) { this.eatObject = eatObject; } public void eat(int type) //吃东西 { this.eatPrepare(type); this.eatObject.eat(type); this.eatFinish(type); } private void eatPrepare(int type) //吃东西之前的准备工作 { if(type == Eat.TypeVegetable) { System.out.println("正在烧菜... ..."); System.out.println("烧菜完成,正在盛菜"); System.out.println("盛菜完成,准备开吃"); } else { System.out.println("正在洗水果,削皮中..."); System.out.println("削皮完成,准备开吃"); } } private void eatFinish(int type) //吃完东西之后的工作 { if(type == Eat.TypeVegetable) { System.out.println("吃完了,准备洗碗..."); } else { System.out.println("吃完了,准备干其它事..."); } } }
最后写测试代码:
public class Test{ public static void main(String args[]) { EatProxy proxy = new EatProxy(new WhatEat()); proxy.eat(Eat.TypeFruit); //通过代理节点吃水果 //分割线 System.out.println(); System.out.println(); proxy.eat(Eat.TypeVegetable); //通过代理节点吃蔬菜 } }
打印如下所示:
从上面可以看到,我们WhatEat类只需要完成吃(核心业务),可以发现通过代理可以降低不同类之间的依赖性
6.总结
学完接口后,它和抽象类之间的区别如下
区别 |
抽象类 |
接口 |
关键字 |
abstract class |
interface |
内部组成 |
支持属性,常量,构造方法,普通方法,abstract抽象方法,静态方法等 |
支持全局常量,abstract抽象方法 |
子类继承 |
class 子类 extends 抽象类{ //... ... } |
class 子类 interface 接口1,接口2,...{ //... ... } |
自身继承 |
抽象类可以继承于多个接口,或者抽象类. |
接口可以继承多个接口,但不能继承抽象类. |
继承限制 |
单继承,一个子类只能继承一个抽象类 |
多继承,一个子类可以继承多个接口 |
未完待续。
原文链接:https://www.cnblogs.com/lifexy/p/10834971.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- 如何干掉 if else 策略+工厂 2020-06-11
- 为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用 2020-06-06
- Java生鲜电商平台-生鲜电商接口幂等性原理与防重复提交方案( 2020-06-05
- Java连载120-反射机制获取构造方法和父类、父接口 2020-06-05
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash