内部类和静态类

上传人:kms****20 文档编号:41011654 上传时间:2018-05-28 格式:DOC 页数:32 大小:59.50KB
返回 下载 相关 举报
内部类和静态类_第1页
第1页 / 共32页
内部类和静态类_第2页
第2页 / 共32页
内部类和静态类_第3页
第3页 / 共32页
内部类和静态类_第4页
第4页 / 共32页
内部类和静态类_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《内部类和静态类》由会员分享,可在线阅读,更多相关《内部类和静态类(32页珍藏版)》请在金锄头文库上搜索。

1、内部类和静态类内部类和静态类内部类 public class Test class A public void setA() public static void main(String args) Test t=new Test(); 调用方式: public class Test2 public static void main(String args) Test test=new Test(); Test.A t=test.new A(); t.setA(); 静态内部类 调用静态内部类的非静态方法: public class Test static class A public voi

2、d setA() public class Test2 public static void main(String args) Test.A a=new Test.A(); a.setA(); 调用静态内部类的静态方法: public class Test static class A static public void setA() public class Test2 public static void main(String args) Test.A.setA(); new Outer.Inner(); / 可以 new Inner(); / 在 Outer 类内部可以 new f

3、oo.Outer.Inner(); / 在包外做内部类实例化, 或者先导包再像第一个那样写. 赵英昌/SC/MDCL 作用呢蒋亚辉/SC/MDCL 不知道。哈哈。我在找找作用看赵英昌/SC/MDCL 好的。 。蒋亚辉/SC/MDCL 幕后英雄的用武之地浅谈 Java 内部类的四个应用场景Java 内部类是 Java 言语的一个很重要的概念, Java 编程思想花了很大的篇幅来讲述这个概念。但是我们在实践中很少用到它,虽然我们在很多时候会被动的使用到它,但它仍然像一个幕后英雄一样,不为我们所知,不为我们所用。本文不试图来讲述 Java 内部类的今生前世、来龙去脉,这些在网络上都已经汗牛充栋。如果

4、读者想了解这些,可以在网络上搜索来学习。Java 内部类总是躲在它的外部类里,像一个幕后英雄一样。但是幕后英雄也有用武之地,在很多时候,恰当的使用 Java 内部类能起到让人拍案叫绝的作用。本文试图谈一谈让这个幕后英雄也有用武之地的四个场景,希望引起大家对使用 Java 内部类的兴趣。以下的文字,要求大家熟悉 Java 内部类的概念后来阅读。场景一:当某个类除了它的外部类,不再被其他的类使用时我们说这个内部类依附于它的外部类而存在,可能的原因有:1、不可能为其他的类使用;2、出于某种原因,不能被其他类引用,可能会引起错误。等等。这个场景是我们使用内部类比较多的一个场景。下面我们以一个大家熟悉的

5、例子来说明。在我们的企业级 Java 项目开发过程中,数据库连接池是一个我们经常要用到的概念。虽然在很多时候,我们都是用的第三方的数据库连接池,不需要我们亲自来做这个数据库连接池。但是,作为我们Java 内部类使用的第一个场景,这个数据库连接池是一个很好的例子。为了简单起见,以下我们就来简单的模拟一下数据库连接池,在我们的例子中,我们只实现数据库连接池的一些简单的功能。如果想完全实现它,大家不妨自己试一试。首先,我们定义一个接口,将数据库连接池的功能先定义出来,如下:public interface Pool extends TimerListener/初始化连接池public boolean

6、 init();/销毁连接池public void destory();/取得一个连接public Connection getConn();/还有一些其他的功能,这里不再列出有了这个功能接口,我们就可以在它的基础上实现数据库连接池的部分功能了。我们首先想到这个数据库连接池类的操作对象应该是由 Connection 对象组成的一个数组,既然是数组,我们的池在取得Connection 的时候,就要对数组元素进行遍历,看看 Connection对象是否已经被使用,所以数组里每一个 Connection 对象都要有一个使用标志。我们再对连接池的功能进行分析,会发现每一个Connection 对象还要

7、一个上次访问时间和使用次数。通过上面的分析,我们可以得出,连接池里的数组的元素应该是由对象组成,该对象的类可能如下:public class PoolConnprivate Connection conn;private boolean isUse;private long lastAccess;private int useCount;下面的省略号省掉的是关于四个属性的一些 get 和 set 方法。我们可以看到这个类的核心就是 Connection,其他的一些属性都是Connection 的一些标志。可以说这个类只有在连接池这个类里有用,其他地方用不到。这时候,我们就该考虑是不是可以把这个

8、类作为一个内部类呢?而且我们把它作为一个内部类以后,可以把它定义成一个私有类,然后将它的属性公开,这样省掉了那些无谓的 get和 set 方法。下面我们就试试看:public class ConnectPool implements Pool/存在 Connection 的数组private PoolConn poolConns;/连接池的最小连接数private int min;/连接池的最大连接数private int max;/一个连接的最大使用次数private int maxUseCount;/一个连接的最大空闲时间private long maxTimeout;/同一时间的 Con

9、nection 最大使用个数private int maxConns;/定时器private Timer timer;public boolean init()trythis.poolConns = new PoolConnthis.min;for(int i=0;iisj)k = isi;isi = isj;isj = k;);这样的用法很多,我们都或多或少的被动的使用过。如在 Swing 编程中,我们经常需要对组件增加监听器对象,如下所示:spinner2.addChangeListener(new ChangeListener()public void stateChanged(Chan

10、geEvent e) System.out.println(“Source: “ + e.getSource(););在 Arrays 包里,对元素为对象的数组的排序:Arrays.sort(emps,new Comparator()Public int compare(Object o1,Object o2)return (Employee)o1).getServedYears()-(Employee)o2).getServedYears(););这样的例子还有很多,JDK 教会了我们很多使用内部类的方法。随时我们都可以看一看 API,看看还会在什么地方使用到内部类呢?场景之四:适当使用内部

11、类,使得代码更加灵活和富有扩展性适当的使用内部类,可以使得你的代码更加灵活和富有扩展性。当然,在这里头起作用的还是一些模式的运行,但如果不配以内部类的使用,这些方法的使用效果就差远了。不信?请看下面的例子:我们记得简单工厂模式的作用就是将客户对各个对象的依赖转移到了工厂类里。很显然,简单工厂模式并没有消除那些依赖,只是简单的将它们转移到了工厂类里。如果有新的对象增加进来,则我们需要修改工厂类。所以我们需要对工厂类做进一步的改造,进一步消除它对具体类的依赖。以前我们提供过一个使用反射来消除依赖的方法;这里,我们将提供另外一种方法。这种方法是将工厂进一步抽象,而将具体的工厂类交由具体类的创建者来实

12、现,这样,工厂类和具体类的依赖的问题就得到了解决。而工厂的使用者则调用抽象的工厂来获得具体类的对象。如下。我们以一个生产形体的工厂为例,下面是这些形体的接口:package polyFactory;public interface Shape public void draw();public void erase();通过上面的描述,大家都可能已经猜到,这个抽象的工厂肯定使用的是模板方法模式。如下:package polyFactory;import java.util.HashMap;import java.util.Map;public abstract class ShapeFacto

13、ry protected abstract Shape create();private static Map factories = new HashMap();public static void addFactory(String id,ShapeFactory f)factories.put(id,f);public static final Shape createShape(String id)if(!factories.containsKey(id)tryClass.forName(“polyFactory.“+id);catch(ClassNotFoundException e

14、)throw new RuntimeException(“Bad shape creation : “+id);return (ShapeFactory)factories.get(id).create();不错,正是模板方法模式的运用。这个类蛮简单的:首先是一个create()方法,用来产生具体类的对象,留交各具体工厂实现去实现。然后是一个 Map 类型的静态变量,用来存放具体工厂的实现以及他们的 ID 号。接着的一个方法使用来增加一个具体工厂的实现。最后一个静态方法是用来获取具体对象,里面的那个Class.forName的作用是调用以 ID 号为类名的类的一些静态的东西。下面,我们来看具体

15、的类的实现:package polyFactory;public class Circle implements Shape public void draw() / TODO Auto-generated method stubSystem.out.println(“the circle is drawing.“);public void erase() / TODO Auto-generated method stubSystem.out.println(“the circle is erasing.“);private static class Factory extends Shape

16、Factoryprotected Shape create()return new Circle();static ShapeFactory.addFactory(“Circle“,new Factory();这个类的其他的地方也平常得很。但就是后面的那个内部类Factory 用得好。第一呢,这个类只做一件事,就是产生一个Circle 对象,与其他类无关,就这一个条也就满足了使用内部类的条件。第二呢,这个 Factory 类需要是静态的,这也得要求它被使用内部类,不然,下面的 ShapeFacotry.addFactory 就没办法 add了。而最后的那个静态的语句块是用来将具体的工厂类添加到抽象的工厂里面去。在抽象工厂里调用 Class.forName

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号