关于java的内部类,尤其匿名类,会感到无法理解
,下文简单实验总结一下。由于内部类涉及很多知识,其中很多没有涉及到。如有表述代码错误,欢迎读者指正!
那为什么使用内部类呢?《thinking in java》第十章中,指出:一般来说,内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类的对象,所以可以认为内部类提供了某些进入其外围类的窗口。其最吸引之处,每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
内部类和接口可以实现c++中的多继承的作用效果。
简单内部类:
上面Contents,Destination类在Parcell1内部,Parcell1对象通过调用函数ship,创建了两内部类的对象,然后通过调用内部类的函数,打印出私有域的值。上述看以看出这两个内部类就如外部类的成员一样,逻辑结构比较简单,我把这种内部类称之为简单内部类,当然也可称成员内部类,同理它可以被权限修饰词修饰,如果是private,则只能在外部类内部被访问,若是public,则可以在任意地方被访问,若是protected,则只能在包内和其子类访问,和普通的类成员没有区别。
要注意的是,在内部类Contents中,打印的是外围类的私有域值,由于内部类可以引用外围类的成员变量及方法,引用格式:
上面局部类放在返回值是接口对象类型的函数中,该类继承了该接口,该题只是简单的打印出了内部类的私有域,其中可以自定义很多内容,读者感兴趣可以尝试。
静态内部类:
如果我们把内部类看成是外部类的成员,则并不矛盾。静态内部类不能只想外部类的引用,而且在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。
匿名类:
匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。
这就要采用另一种形式 的new语句,如下所示:
new <类或接口> <匿名类的主体>
这种形式的new语句声明一个 新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是 new语句的操作数,后跟匿名类的主体。
上面我们不知道一个匿名类的名字,而return new prr()这一句很让人寻味,好像在实例化一个prr对象(接口是高级抽象类,当然不能被实例化),但是此时又恰好创建一个类,但是我们无法知道它的名字。
我们把上面的匿名内部类改成一般形式:
我们发现使用抽象类很简洁,但是要注意几点:
1.匿名内部类是没有访问修饰符的。
2.new 匿名内部类,这个类(接口)首先是要存在的。
3.匿名内部类是没有构造方法。
文章参考:
( http://www.cnblogs.com/dolphin0520/p/3811445.html , http://blog.csdn.net/yu422560654/article/details/7466260 )
那为什么使用内部类呢?《thinking in java》第十章中,指出:一般来说,内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类的对象,所以可以认为内部类提供了某些进入其外围类的窗口。其最吸引之处,每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
内部类和接口可以实现c++中的多继承的作用效果。
简单内部类:
点击(此处)折叠或打开
- public class Parcell1 {
-
- private int i = 5;
-
- class Contents{
-
- private int i = 1;
- public int value(){ return Parcell1.this.i;}
-
- }
- class Destination{
-
- private String label;
- private int i = 6;
-
- Destination(String whereTo){
-
- label = whereTo;
- }
-
- String readLabel(){ return label;}
-
-
- public void ship(String dest){
-
- Contents c = new Contents();
- System.out.println(value());
- Destination d = new Destination(dest);
- System.out.println(d.readLabel());
-
- }
- public static void main(String[] args){
-
- Parcell1 p = new Parcell1();
- p.ship("wang");
-
- }
- }
要注意的是,在内部类Contents中,打印的是外围类的私有域值,由于内部类可以引用外围类的成员变量及方法,引用格式:
外部类.this.成员变量
外部类.this.成员方法
局部内部类:
顾名思义,这种类定义在方法内或者域内,而且它的作用域也局限于方法和域内,不能被访问权限修饰词所修饰。
顾名思义,这种类定义在方法内或者域内,而且它的作用域也局限于方法和域内,不能被访问权限修饰词所修饰。
点击(此处)折叠或打开
- interface pr {
-
- void print1();
-
- }
点击(此处)折叠或打开
- public class Parcell2 {
-
- private int i = 5;
-
- public pr ship(String wang){
- class Destination implements pr {
-
- private String label;
- private int i = 6;
-
- Destination(String whereTo){
-
- label = whereTo;
- RetrunLabel();
- }
- public void print1() {
-
- System.out.println(label);
- }
-
- public void RetrunLabel(){
-
- System.out.println(label);
- }
- }
- return new Destination(wang);
- }
-
-
- public static void main(String[] args){
-
- Parcell2 p = new Parcell2();
- pr wang = p.ship("wang");
- }
- }
静态内部类:
如果我们把内部类看成是外部类的成员,则并不矛盾。静态内部类不能只想外部类的引用,而且在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。
点击(此处)折叠或打开
- public class Parcell3 {
-
- private int i = 5;
- static class Destination{
-
- private String label;
- private static int i = 5;
- //private static int j = 6; //error if the class is not static
- Destination(String whereTo){
-
- label = whereTo;
- }
-
- int readi(){ return i;} //Parcell3.this.i; error
-
- }
-
- public void ship(String dest){
-
- Destination d = new Destination(dest);
- System.out.println(d.readi());
-
- }
- public static void main(String[] args){
-
- Parcell3 p = new Parcell3();
- p.ship("wang");
-
- }
- }
匿名类:
匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。
这就要采用另一种形式 的new语句,如下所示:
new <类或接口> <匿名类的主体>
这种形式的new语句声明一个 新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是 new语句的操作数,后跟匿名类的主体。
点击(此处)折叠或打开
- public interface prr {
-
- String print1();
- String geti();
- }
点击(此处)折叠或打开
- public class Parcell4 {
-
- private int i = 5;
- private String ss;
-
- Parcell4(String ss){
-
- this.ss = ss;
- }
-
- public prr ship(String qq){
-
- return new prr(){
-
- public String print1() {
-
- return ss + qq;
- }
-
- public String geti(){
-
- return "Lios" + "\n" +i;
- }
- };
-
- }
-
- public static void main(String[] args){
-
- Parcell4 p = new Parcell4("diy_");
- prr c = p.ship("os");
- String s = p.ship("os").print1();
- System.out.println(s);
- System.out.println(c.geti());
-
- }
- }
上面我们不知道一个匿名类的名字,而return new prr()这一句很让人寻味,好像在实例化一个prr对象(接口是高级抽象类,当然不能被实例化),但是此时又恰好创建一个类,但是我们无法知道它的名字。
我们把上面的匿名内部类改成一般形式:
点击(此处)折叠或打开
- package 第十章内部类;
-
- public interface prr {
-
- String print1(String bb);
- String geti();
- }
点击(此处)折叠或打开
- public class Parcell5 {
-
- private int i = 5;
- private String ss;
-
- Parcell5(String ss){
-
- this.ss = ss;
- }
-
- class WANG implements prr{
-
- public String print1(String bb) {
-
- return ss + bb;
- }
-
- public String geti(){
-
- return "Lios" + "\n" +i;
- }
- }
-
- public prr ship(){
-
- return new WANG();
- }
-
- public static void main(String[] args){
-
- Parcell5 p = new Parcell5("diy_");
- prr c = p.ship();
- String s = p.ship().print1("os");
- System.out.println(s);
- System.out.println(c.geti());
-
- }
- }
我们发现使用抽象类很简洁,但是要注意几点:
1.匿名内部类是没有访问修饰符的。
2.new 匿名内部类,这个类(接口)首先是要存在的。
3.匿名内部类是没有构造方法。
文章参考:
( http://www.cnblogs.com/dolphin0520/p/3811445.html , http://blog.csdn.net/yu422560654/article/details/7466260 )
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29876893/viewspace-1816069/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29876893/viewspace-1816069/