首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

内部类小结

2012-07-23 
内部类总结:?public?interface?Contents?{???????int?value()???}?????public?interface?Destination?{??

内部类总结:

?

public?interface?Contents?{???
内部类小结????int?value();???
内部类小结}???
内部类小结??
内部类小结public?interface?Destination?{???
内部类小结????String?readLabel();???
内部类小结}???
内部类小结??
内部类小结public?class?Goods?{???
内部类小结????private?class?Content?implements?Contents?{???
内部类小结????????private?int?i?=?11;???
内部类小结????????public?int?value()?{????
内部类小结????????????return?i;????
内部类小结????????}???
内部类小结????}???
内部类小结??
内部类小结????protected?class?GDestination?implements?Destination?{???
内部类小结????????private?String?label;???
内部类小结????????private?GDestination(String?whereTo)?{???
内部类小结????????????label?=?whereTo;???
内部类小结????????}???
内部类小结????????public?String?readLabel()?{????
内部类小结????????????return?label;????
内部类小结????????}???
内部类小结????}???
内部类小结??
内部类小结????public?Destination?dest(String?s)?{???
内部类小结????????return?new?GDestination(s);???
内部类小结????}???
内部类小结????public?Contents?cont()?{???
内部类小结????????return?new?Content();???
内部类小结????}???
内部类小结}???
内部类小结??
内部类小结class?TestGoods?{???
内部类小结????public?static?void?main(String[]?args)?{???
内部类小结????????Goods?p?=?new?Goods();???
内部类小结????????Contents?c?=?p.cont();???
内部类小结????????Destination?d?=?p.dest("Beijing");???
内部类小结????}???
内部类小结}???
内部类小结
在这个例子里类Content和GDestination被定义在了类Goods内部,并且分别有着protected和private修饰符来控制访问级别。Content代表着Goods的内容,而GDestination代表着Goods的目的地。它们分别实现了两个接口Content和Destination。在后面的main方法里,直接用 Contents c和Destination d进行操作,你甚至连这两个内部类的名字都没有看见!这样,内部类的第一个好处就体现出来了——隐藏你不想让别人知道的操作,也即封装性。?
同时,我们也发现了在外部类作用范围之外得到内部类对象的第一个方法,那就是利用其外部类的方法创建并返回。上例中的cont()和dest()方法就是这么做的。那么还有没有别的方法呢?当然有,其语法格式如下:?
内部类小结outerObject=new?outerClass(Constructor?Parameters);?
内部类小结
内部类小结outerClass.innerClass?innerObject=outerObject.new?InnerClass(Constructor?Parameters);?
内部类小结
内部类小结
注意在创建非静态内部类对象时,一定要先创建起相应的外部类对象。至于原因,也就引出了我们下一个话题——?

非静态内部类对象有着指向其外部类对象的引用?
对刚才的例子稍作修改:?
内部类小结public?class?Goods?{???
内部类小结??
内部类小结????private?valueRate=2;???
内部类小结??
内部类小结????private?class?Content?implements?Contents?{???
内部类小结????????private?int?i?=?11*valueRate;???
内部类小结????????public?int?value()?{????
内部类小结????????????return?i;????
内部类小结????????}???
内部类小结????}???
内部类小结??
内部类小结????protected?class?GDestination?implements?Destination?{???
内部类小结????????private?String?label;???
内部类小结????????private?GDestination(String?whereTo)?{???
内部类小结????????????label?=?whereTo;???
内部类小结????????}???
内部类小结????????public?String?readLabel()?{????
内部类小结????????????return?label;????
内部类小结????????}???
内部类小结????}???
内部类小结??
内部类小结????public?Destination?dest(String?s)?{???
内部类小结????????return?new?GDestination(s);???
内部类小结????}???
内部类小结????public?Contents?cont()?{???
内部类小结????????return?new?Content();???
内部类小结????}???
内部类小结}???
内部类小结

修改的部分用红色显示了。在这里我们给Goods类增加了一个private成员变量valueRate,意义是货物的价值系数,在内部类Content的方法value()计算价值时把它乘上。我们发现,value()可以访问valueRate,这也是内部类的第二个好处——一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量!这是一个非常有用的特性,为我们在设计时提供了更多的思路和捷径。要想实现这个功能,内部类对象就必须有指向外部类对象的引用。outerClass.this?


静态内部类?
和普通的类一样,内部类也可以有静态的。不过和非静态内部类相比,区别就在于静态内部类没有了指向外部的引用。这实际上和C++中的嵌套类很相像了,public?class?Goods1?{???
内部类小结?????public?Destination?dest(String?s)?{???
内部类小结??????????class?GDestination?implements?Destination?{???
内部类小结???????????????private?String?label;???
内部类小结???????????????private?GDestination(String?whereTo)?{???
内部类小结????????????????????label?=?whereTo;???
内部类小结???????????????}???
内部类小结???????????????public?String?readLabel()?{?return?label;?}???
内部类小结??????????}???
内部类小结??????????return?new?GDestination(s);???
内部类小结?????}???
内部类小结??
内部类小结?????public?static?void?main(String[]?args)?{???
内部类小结??????????Goods1?g=?new?Goods1();???
内部类小结??????????Destination?d?=?g.dest("Beijing");???
内部类小结?????}???
内部类小结}??
内部类小结

上面就是这样一个例子。在方法dest中我们定义了一个内部类,最后由这个方法返回这个内部类的对象。如果我们在用一个内部类的时候仅需要创建它的一个对象并创给外部,就可以这样做。当然,定义在方法中的内部类可以使设计多样化,用途绝不仅仅在这一点。下面有一个更怪的例子:?
内部类小结public?class?Goods2{???
内部类小结?????private?void?internalTracking(boolean?b)?{???
内部类小结??????????if(b)?{???
内部类小结???????????????class?TrackingSlip?{???
内部类小结????????????????????private?String?id;???
内部类小结????????????????????TrackingSlip(String?s)?{???
内部类小结?????????????????????????id?=?s;???
内部类小结????????????????????}???
内部类小结????????????????????String?getSlip()?{?return?id;?}???
内部类小结???????????????}???
内部类小结???????????????TrackingSlip?ts?=?new?TrackingSlip("slip");???
内部类小结???????????????String?s?=?ts.getSlip();???
内部类小结??????????}????
内部类小结?????}???
内部类小结??
内部类小结?????public?void?track()?{?internalTracking(true);?}???
内部类小结??
内部类小结?????public?static?void?main(String[]?args)?{???
内部类小结??????????Goods2?g=?new?Goods2();???
内部类小结??????????g.track();???
内部类小结?????}???
内部类小结}???
内部类小结
你不能在if之外创建这个内部类的对象,因为这已经超出了它的作用域。不过在编译的时候,内部类TrackingSlip和其他类一样同时被编译,只不过它由它自己的作用域,超出了这个范围就无效,除此之外它和其他内部类并没有区别。?


匿名内部类?
new?interfacename(){内部类小结内部类小结};?
内部类小结或?new?superclassname(){内部类小结内部类小结};?
内部类小结public?class?Goods3?{???
内部类小结?????public?Contents?cont(){???
内部类小结??????????return?new?Contents(){???
内部类小结???????????????private?int?i?=?11;???
内部类小结???????????????public?int?value()?{????
内部类小结????????????????????return?i;????
内部类小结???????????????}???
内部类小结??????????};???
内部类小结?????}???
内部类小结}???
内部类小结这里方法cont()使用匿名内部类直接返回了一个实现了接口Contents的类的对象,看上去的确十分简洁。

在frame.addWindowListener(new?WindowAdapter(){???
内部类小结?????public?void?windowClosing(WindowEvent?e){???
内部类小结??????????System.exit(0);????
内部类小结?????}???
内部类小结});???
内部类小结有一点需要注意的是,匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用super关键字调用相应的内容)。如果你想要初始化它的成员变量,有下面几种方法:?

如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为final。?
将匿名内部类改造成有名字的局部内部类,这样它就可以拥有构造函数了。?
在这个匿名内部类中使用初始化代码块。?


为什么需要内部类??
public?final?class?ParseState?{
内部类小结????????内部类小结..
内部类小结????private?static?final?char?TAB?=?'\t';
内部类小结
内部类小结????/**
内部类小结?????*?Marker?interface?for?entries?into?the?{@link?ParseState}.
内部类小结?????*/
内部类小结????public?interface?Entry?{
内部类小结
内部类小结????}
内部类小结
内部类小结}
内部类小结
内部接口的实现类:
内部类小结public?class?QualifierEntry?implements?ParseState.Entry?{
内部类小结
内部类小结????private?String?typeName;
内部类小结
内部类小结
内部类小结????public?QualifierEntry(String?typeName)?{
内部类小结????????if?(!StringUtils.hasText(typeName))?{
内部类小结????????????throw?new?IllegalArgumentException("Invalid?qualifier?type?'"?+?typeName?+?"'.");
内部类小结????????}
内部类小结????????this.typeName?=?typeName;
内部类小结????}
内部类小结
内部类小结????public?String?toString()?{
内部类小结????????return?"Qualifier?'"?+?this.typeName?+?"'";
内部类小结????}
内部类小结
内部类小结}
这样,QualifierEntry实例就可以访问ParseState的任意成员变量。

?

热点排行