java内部类:浅析Java语言中的内部类来源: 发布时间:星期四, 2009年2月12日 浏览:156次 评论:0
提起Java内部类(Inner Class)可能很多人不太熟悉实际上类似概念在C里也有那就是嵌套类(Nested Class)有关这两者区别和联系在下文中会有对比内部类从表面上看就是在类中又定义了个类(下文会看到内部类可以在很多地方定义)而实际上并没有那么简单乍看上去内部类似乎有些多余它用处对于初学者来说可能并不是那么显著但是随着对它深入了解你会发现Java设计者在内部类身上确是用心良苦学会使用内部类是掌握Java高级编程部分它可以让你更优雅地设计你结构下面从以下几个方面来介绍: 第次见面 public erface Contents { value; } public erface Destination { String readLabel; } public Goods { private Content implements Contents { private i = 11; public value { i; } } protected GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel { label; } } public Destination dest(String s) { GDestination(s); } public Contents cont { Content; } } TestGoods { public void (String args) { Goods p = Goods; Contents c = p.cont; Destination d = p.dest("Beijing"); } } 在这个例子里类Content和GDestination被定义在了类Goods内部并且分别有着protected和private修饰符来控制访问级别Content代表着Goods内容而GDestination代表着Goods目地它们分别实现了两个接口Content和Destination在后面思路方法里直接用 Contents c和Destination d进行操作你甚至连这两个内部类名字都没有看见!这样内部类第个好处就体现出来了??隐藏你不想让别人知道操作也即封装性 同时我们也发现了在外部类作用范围的外得到内部类对象第个思路方法那就是利用其外部类思路方法创建并返回上例中cont和dest思路方法就是这么做那么还有没有别思路方法呢?当然有其语法格式如下: outerObject= outerClass(Constructor Parameters); outerClass.innerClass innerObject=outerObject. InnerClass(Constructor Parameters); 注意在创建非静态内部类对象时定要先创建起相应外部类对象至于原因也就引出了我们下个话题??非静态内部类对象有着指向其外部类对象引用对刚才例子稍作修改: public Goods { private valueRate=2; private Content implements Contents { private i = 11*valueRate; public value { i; } } protected GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel { label; } } public Destination dest(String s) { GDestination(s); } public Contents cont { Content; } } 修改部分用蓝色显示了在这里我们给Goods类增加了个private成员变量valueRate意义是货物价值系数在内部类Content思路方法value计算价值时把它乘上我们发现value可以访问valueRate这也是内部类第 2个好处??个内部类对象可以访问创建它外部类对象内容甚至包括私有变量!这是个非常有用特性为我们在设计时提供了更多思路和捷径要想实现这个功能内部类对象就必须有指向外部类对象引用Java编译器在创建内部类对象时隐式把其外部类对象引用也传了进去并直保存着这样就使得内部类对象始终可以访问其外部类对象同时这也是为什么在外部类作用范围的外向要创建内部类对象必须先创建其外部类对象原因 有人会问如果内部类里个成员变量和外部类个成员变量同名也即外部类同名成员变量被屏蔽了如何办?没事Java里用如下格式表达外部类引用: outerClass.this 有了它我们就不怕这种屏蔽情况了 静态内部类 和普通类样内部类也可以有静态不过和非静态内部类相比区别就在于静态内部类没有了指向外部引用这实际上和C中嵌套类很相像了Java内部类和C嵌套类最大区别就在于是否有指向外部引用这点上当然从设计角度以及以它些细节来讲还有区别 除此的外在任何非静态内部类中都不能有静态数据静态思路方法或者又个静态内部类(内部类嵌套可以不止层)不过静态内部类中却可以拥有这切这也算是两者第 2个区别吧 局部内部类 是Java内部类也可以是局部它可以定义在个思路方法甚至个代码块的内 public Goods1 { public Destination dest(String s) { GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel { label; } } GDestination(s); } public void (String args) { Goods1 g= Goods1; Destination d = g.dest("Beijing"); } } 上面就是这样个例子在思路方法dest中我们定义了个内部类最后由这个思路方法返回这个内部类对象如果我们在用个内部类时候仅需要创建它个对象并创给外部就可以这样做当然定义在思路方法中内部类可以使设计多样化用途绝不仅仅在这点 下面有个更怪例子: public Goods2{ private void ernalTracking(boolean b) { (b) { TrackingSlip { private String id; TrackingSlip(String s) { id = s; } String getSlip { id; } } TrackingSlip ts = TrackingSlip("slip"); String s = ts.getSlip; } } public void track { ernalTracking(true); } public void (String args) { Goods2 g= Goods2; g.track; } } 你不能在的外创建这个内部类对象这已经超出了它作用域不过在编译时候内部类TrackingSlip和其他类样同时被编译只不过它由它自己作用域超出了这个范围就无效除此的外它和其他内部类并没有区别 匿名内部类 java匿名内部类语法规则看上去有些古怪不过如同匿名样当你只需要创建个类对象而且用不上它名字时使用内部类可以使代码看上去简洁清楚它语法规则是这样: erfacename{......}; 或 supername{......}; 下面接着前面继续举例子: public Goods3 { public Contents cont{ Contents{ private i = 11; public value { i; } }; } } 这里思路方法cont使用匿名内部类直接返回了个实现了接口Contents类对象看上去确十分简洁 在java事件处理匿名适配器中匿名内部类被大量使用例如在想关闭窗口时加上这样句代码: frame.addWindowListener( WindowAdapter{ public void windowClosing(WindowEvent e){ .exit(0); } }); 有点需要注意是匿名内部类由于没有名字所以它没有构造(但是如果这个匿名内部类继承了个只含有带参数构造父类创建它时候必须带上这些参数并在实现过程中使用super关键字相应内容)如果你想要化它成员变量有下面几种思路方法: 如果是在个思路方法匿名内部类可以利用这个思路方法传进你想要参数不过记住这些参数必须被声明为final 将匿名内部类改造成有名字局部内部类这样它就可以拥有构造了 在这个匿名内部类中使用化代码块 为什么需要内部类? java内部类有什么好处?为什么需要内部类? 首先举个简单例子如果你想实现个接口但是这个接口中个思路方法和你构想这个类中个思路方法名称参数相同你应该如何办?这时候你可以建个内部类实现这个接口由于内部类对外部类所有内容都是可访问所以这样做可以完成所有你直接实现这个接口功能 不过你可能要质疑更改下思路方法不就行了吗? 确以此作为设计内部类理由实在没有说服力 真正原因是这样java中内部类和接口加在起可以解决常被C员抱怨java中存在个问题??没有多继承实际上C多继承设计起来很复杂而java通过内部类加上接口可以很好实现多继承效果 0
相关文章读者评论发表评论 |
|