您的位置:首页 > 职场人生

黑马程序员——10程序的扩展:多态与反射

2014-06-27 15:32 267 查看
  ------- android培训java培训、期待与您交流! ----------

从目前来学的看,提高程序的扩展性有两种手段:多态与反射,这两种机制又有什么不同呢?

1.多态:

提起多态就不得不提抽象类和接口,因为多态是建立在继承或实现上的,因为多态就是父类指向子类对象。

抽象类与接口最大的区别就是单继承与多实现了,此外另一个比较明显的区别就是抽象函数可以定义普通方法。

比如我们动物园的饲养人员要喂养动物,饲养员有feed方法,动物有eat方法,他要喂养的动物有很多,我们不可能为饲养员提供喂养各种动物的方法,只能为他提供一个feed方法,但是他接受的参数是动物们的父类Animal,这样就用到了多态。

[java] view
plaincopy





public class Main {  

  

    public static void main(String[] args) {  

          

        //喂狗  

          Feeder.feed(new Dog());  

         //喂猫  

          Feeder.feed(new Cat());  

    }  

}  

[java] view
plaincopy





<p>public class Feeder {</p><p> public static void feed(Animal animal)  //参数列表是父类,主函数中传入的确实子类的对象,这就是多态  

 {  

  animal.eat();  

 }  

}</p>  

[java] view
plaincopy





<p>public abstract class Animal {</p><p> public abstract void eat();  

    

}</p>  

[java] view
plaincopy





public class Cat extends Animal  

{  

 @Override  

    public void eat()  

    {  

     System.out.println("吃鱼");  

    }  

   

 public void catchMouse()         //如果将父类Animal换为一个接口,那么子类实现的时候就不能定义自己的方法  

 {  

    

 }  

}  

[java] view
plaincopy





<p>public class Dog extends Animal  

{  

   

 public void eat()  

 {  

  System.out.println("啃骨头");  

 }</p><p>}</p>  

一般情况下是推荐使用接口的,除非子类需要自己独特的方法。

2.反射

如何利用反射来提高程序的扩展性呢?

通常的方法就是在程序加载的时候加载配置表(Properties或者XML)

多态和反射最大的区别就在于:扩展程序时多态需要修改源代码,比如上面的例子,想要喂猫就得new一个猫对象,

而反射只要修改一下配置表就欧了。

下面列举一个给电脑主板扩展功能的例子。

先使用多态实现:

[java] view
plaincopy





public class Main {  

public static void main(String[] arr)  

{  

    // 添加声卡  

    MainBoader.runPCI(new SounderCard());    

    //添加网卡  

    MainBoader.runPCI(new WebCard());  // 添加的时候都要修改源代码  

}  

}  

[java] view
plaincopy





<p>public class MainBoader {</p><p> public static void runPCI (PCI p)  

 {  

  p.open();  

  p.close();  

 }  

}</p>  

[java] view
plaincopy





interface PCI   //添加到主板上的设备都要实现的规则  

{  

 void open();  

 void close();  

}  

[java] view
plaincopy





public class SounderCard implements PCI  

{  

 @Override  

 public void open()  

 {  

  System.out.println("声卡运行");  

 }  

 @Override  

 public void close()  

 {  

  System.out.println("声卡关闭");  

 }  

}  

[java] view
plaincopy





public class WebCard implements PCI  

{  

    @Override  

 public void open()  

 {  

  System.out.println("网卡运行");  

 }  

    @Override  

 public void close()  

 {  

  System.out.println("网卡关闭");  

 }  

}  

使用反射实现:

[java] view
plaincopy





package cn.com;  

  

import java.io.File;  

import java.io.FileInputStream;  

import java.io.FileOutputStream;  

import java.io.IOException;  

import java.io.InputStream;  

import java.io.InputStreamReader;  

import java.util.Properties;  

  

public class Main {  

public static void main(String[] arr)throws Exception  

{  

//  // 添加声卡  

//  MainBoader.run(new SounderCard());    

//  //添加网卡  

//  MainBoader.run(new WebCard());  // 添加的时候都要修改源代码  

      

    MainBoader mb = new MainBoader();  

      

    //反射就是通过类的字节码文件(就是编译后的class文件)来获取类的信息,  

    //所以上面的PCI接口,声卡、网卡类还要使用,我们所做的工作就是利用反射来操作这些类  

      

    //先将一个配置文件封装成对象  

    File file = new File("D://config.properties");  

    //加载配置文件  

    FileInputStream fis = new FileInputStream(file);  

    Properties p = new Properties();  

    p.load(fis);  

      

    for(int i = 0; i < p.size(); i++ )  

    {  

        //读取配置文件中的内容, 其实就是获得类名,以便获得类的字节码文件  

        String str = p.getProperty("PCI"+(i+1));  

        //获取类的字节码文件  

        Class c = Class.forName(str);  

        // 实例化一个类的对象  

        PCI pci = (PCI)c.newInstance();  

          

        mb.runPCI(pci);               

    }                 

}  

}  

我们写好上面的代码之后,如果想要再添加一个显卡graphicsCard,只要在配置文件中加上下面的键值对就可以了

PCI3=cn.com.graphicsCard

当然要事先写好一个实现了PCI接口的graphicsCard类。

[java] view
plaincopy





package cn.com;  

  

import java.io.File;  

import java.io.FileInputStream;  

import java.io.FileOutputStream;  

import java.io.IOException;  

import java.io.InputStream;  

import java.io.InputStreamReader;  

import java.util.Properties;  

  

public class Main {  

public static void main(String[] arr)throws Exception  

{  

//  // 添加声卡  

//  MainBoader.run(new SounderCard());    

//  //添加网卡  

//  MainBoader.run(new WebCard());  // 添加的时候都要修改源代码  

      

    MainBoader mb = new MainBoader();  

      

    //反射就是通过类的字节码文件(就是编译后的class文件)来获取类的信息,  

    //所以上面的PCI接口,声卡、网卡类还要使用,我们所做的工作就是利用反射来操作这些类  

      

    //先将一个配置文件封装成对象  

    File file = new File("D://config.properties");  

    //加载配置文件  

    FileInputStream fis = new FileInputStream(file);  

    Properties p = new Properties();  

    p.load(fis);  

      

    for(int i = 0; i < p.size(); i++ )  

    {  

        //读取配置文件中的内容, 其实就是获得类名,以便获得类的字节码文件  

        String str = p.getProperty("PCI"+(i+1));  

        //获取类的字节码文件  

        Class c = Class.forName(str);  

        // 实例化一个类的对象  

        PCI pci = (PCI)c.newInstance();  

          

        mb.runPCI(pci);               

    }                 

}  

}  

  ------- android培训java培训、期待与您交流! ----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息