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

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


 

 


 


 

 

 ------- android培训java培训、期待与您交流!-------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值