------- android培训、java培训、期待与您交流!----------
从目前来学的看,提高程序的扩展性有两种手段:多态与反射,这两种机制又有什么不同呢?
1.多态:
提起多态就不得不提抽象类和接口,因为多态是建立在继承或实现上的,因为多态就是父类指向子类对象。
抽象类与接口最大的区别就是单继承与多实现了,此外另一个比较明显的区别就是抽象函数可以定义普通方法。
比如我们动物园的饲养人员要喂养动物,饲养员有feed方法,动物有eat方法,他要喂养的动物有很多,我们不可能为饲养员提供喂养各种动物的方法,只能为他提供一个feed方法,但是他接受的参数是动物们的父类Animal,这样就用到了多态。
public class Main {
public static void main(String[] args) {
//喂狗
Feeder.feed(new Dog());
//喂猫
Feeder.feed(new Cat());
}
}
<p>public class Feeder {</p><p> public static void feed(Animal animal) //参数列表是父类,主函数中传入的确实子类的对象,这就是多态
{
animal.eat();
}
}</p>
<p>public abstract class Animal {</p><p> public abstract void eat();
}</p>
public class Cat extends Animal
{
@Override
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse() //如果将父类Animal换为一个接口,那么子类实现的时候就不能定义自己的方法
{
}
}
<p>public class Dog extends Animal
{
public void eat()
{
System.out.println("啃骨头");
}</p><p>}</p>
一般情况下是推荐使用接口的,除非子类需要自己独特的方法。
2.反射
如何利用反射来提高程序的扩展性呢?
通常的方法就是在程序加载的时候加载配置表(Properties或者XML)
多态和反射最大的区别就在于:扩展程序时多态需要修改源代码,比如上面的例子,想要喂猫就得new一个猫对象,
而反射只要修改一下配置表就欧了。
下面列举一个给电脑主板扩展功能的例子。
先使用多态实现:
public class Main {
public static void main(String[] arr)
{
// 添加声卡
MainBoader.runPCI(new SounderCard());
//添加网卡
MainBoader.runPCI(new WebCard()); // 添加的时候都要修改源代码
}
}
<p>public class MainBoader {</p><p> public static void runPCI (PCI p)
{
p.open();
p.close();
}
}</p>
interface PCI //添加到主板上的设备都要实现的规则
{
void open();
void close();
}
public class SounderCard implements PCI
{
@Override
public void open()
{
System.out.println("声卡运行");
}
@Override
public void close()
{
System.out.println("声卡关闭");
}
}
public class WebCard implements PCI
{
@Override
public void open()
{
System.out.println("网卡运行");
}
@Override
public void close()
{
System.out.println("网卡关闭");
}
}
使用反射实现:
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类。
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);
}
}
}