10.JAVA-接口、工厂模式、代理模式、详解
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();
}
}
打印如下:
从上面代码可以看出,通过工厂模式,我们可以更加容易地管理多个相同接口的子类们的操作.
PS:当前工厂模式还是最简单的,在后续学到反射机制泛型后,在讲解.
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,...{ //... ... } |
自身继承 |
抽象类可以继承于多个接口,或者抽象类. |
接口可以继承多个接口,但不能继承抽象类. |
继承限制 |
单继承,一个子类只能继承一个抽象类 |
多继承,一个子类可以继承多个接口 |
下章学习:11.JAVA-Object类之finalize(),clone(),toString()等方法覆写
10.JAVA-接口、工厂模式、代理模式、详解的更多相关文章
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- Java进阶 | Proxy动态代理机制详解
一.Jvm加载对象 在说Java动态代理之前,还是要说一下Jvm加载对象的过程,这个依旧是理解动态代理的基础性原理: Java类即源代码程序.java类型文件,经过编译器编译之后就被转换成字节代码.c ...
- java Proxy InvocationHandler 动态代理实现详解
spring 两大思想,其一是IOC,其二就是AOP..而AOP的原理就是java 的动态代理机制.这里主要记录java 动态代理的实现及相关类的说明. java 动态代理机制依赖于Invocati ...
- 理解java的三种代理模式
代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下,实现对目标对象的功能扩展. 比如有个歌手对象叫Singer,这个对象有一个唱歌方法叫sing(). 1 public class ...
- java设计模式之Proxy(代理模式)
java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...
- 黑马程序员:Java基础总结----静态代理模式&动态代理
黑马程序员:Java基础总结 静态代理模式&动态代理 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public class Ts { ...
- Java的三种代理模式
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
- Java设计模式之《代理模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6525527.html 代理模式算是我接触较早的模式,代理就是中介,中间人.法律上也有代理, ...
- Java的三种代理模式简述
本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇博文中讲述. 代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下, ...
- Java的三种代理模式(Spring动态代理对象)
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
随机推荐
- linux网络配置及IP绑定
在学习时,参考了这篇文章:http://blog.csdn.net/collection4u/article/details/14127671:在这篇文章中作者讲述了VMware中虚机的三种网络模式: ...
- ⭐register_chrdev、register_chrdev_region以及alloc_chrdev_region之间的区别
register_chrdev:Linux2.6.30之前所用,不用定义cdev:但 如果是register_chrdev 注册的话,这个时候,分配的次设备号,是从0~255,这样子的话,就分配的范围 ...
- NIO与IO的区别
nio是new io的简称,从jdk1.4就被引入了.现在的jdk已经到了1.6了,可以说不是什么新东西了.但其中的一些思想值得我来研究.这两天,我研究了下其中的套接字部分,有一些心得,在此分享. ...
- 利用百度地图API制作房产酒店地图
摘要: 想亲手制作一张酷讯.去哪儿.安居客.链接地产那样的房产.酒店地图麼?那赶快来学习吧.(以酷讯为例,如下图) 更多成功案例请点击:http://dev.baidu.com/wiki/map/in ...
- [Selenium] Automation Test Manual(Selenium)
http://www.cnblogs.com/puresoul/p/3483055.html http://www.360doc.com/content/14/0913/10/13497042_409 ...
- LRU原理和Redis实现——一个今日头条的面试题
看了评论,发现有些地方有问题,更新了图和一些描述,希望可以更清晰一些,也欢迎关注,还会有干货文章 -------- 很久前参加过今日头条的面试,遇到一个题,目前半部分是如何实现 LRU,后半部分是 R ...
- CreateRemoteThread注入DLL
DLL注入的常用方式之一远程线程注入,实现代码如下 // CreateRemoteThread.cpp : Defines the entry point for the application.// ...
- 移动端网页巧用 margin和padding 的百分比实现自适应
一个基础却又容易混淆的css知识点 本文依赖于一个基础却又容易混淆的css知识点:当margin/padding取形式为百分比的值时,无论是left/right,还是top/bottom,都是以父元素 ...
- BZOJ[4127] Abs
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4127 不算难的样子,才见过此类模型. 首先可以发现每次修改只增不减,那么这$O(n)$的负数最 ...
- A. Meeting of Old Friends
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...