欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

10.JAVA-接口、工厂模式、代理模式、详解

程序员文章站 2022-07-02 18:06:50
1.接口定义 接口属于一个特殊的类,这个类里面只能有抽象方法和全局常量 (该概念在JDK1.8之后被打破,在1.8后接口中还可以定义普通方法和静态方法,在后续章节会详讲) 1.1 接口具有以下几个原则 接口通过interface关键字来实现定义 一个子类如果要继承接口的话,则需要通过implemen ......

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();
         }
}

运行打印:

 10.JAVA-接口、工厂模式、代理模式、详解

从上面代码可以看出,接口实际上只是表示一种操作标准  ,而接口本身其实是没有操作能力的,需要子类去实现这个操作能力才行.

 

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();
         }
}

打印如下:

 10.JAVA-接口、工厂模式、代理模式、详解

从上面代码可以看出,通过工厂模式,我们可以更加容易地管理多个相同接口的子类们的操作.

 

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);             //通过代理节点吃蔬菜
         }
}

打印如下所示:

 10.JAVA-接口、工厂模式、代理模式、详解

从上面可以看到,我们whateat类只需要完成吃(核心业务),可以发现通过代理可以降低不同类之间的依赖性

 

未完待续。