Java内部类总结
2013-02-26 13:47
190 查看
Java的内部类一共有四种,分别是静态内部类,成员内部类,局部内部类和匿名内部类。有时候,我们很难记住四种内部类,不妨这样想,四种内部类对应了Java类的四种组成,Java有静态方法和静态变量,那静态内部类就是和这个对应着,而类有成员函数和成员变量那一定也就有成员内部类;Java有局部变量也就对应了局部内部类;最后,匿名内部类对应了我们new一个对象,这样想,四种内部类就比较好掌握了。废话少说,逐一介绍。
静态内部类:
静态内部类有两个特点:
1. 静态内部类使用static修饰,声明在类体中
2. 静态内部类可以访问外部累的静态成员(就好像静态方法可以访问静态变量一样)
看代码:
成员内部类
成员内部类有两个特点:
1. 声明在类体中,不使用static,具有类的成员特征,也就是,必须使用外部类的实例才能创建内部类实例
2. 内部类实例可以访问外部类的成员变量
看代码:
局部内部类
把类声明在方法中,就是局部内部类,作用域类似局部变量
看代码
匿名内部类
在长篇幅的说明匿名内部类这个非常重要的概念前,我们先用简单的话说明什么是匿名内部类。
举例子
匿名类是不能有名称的类,所以没有办法引用他们。必须在创建时,作为new语句的一部分类声明匿名类,这就要采用另一种形式的new语句,如下所示: new <类或接口> <类的主体> 这种形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口。它还创建那个类的一个新实例,并把它作为语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数,后跟匿名类的主体。如果匿名类对另一个类进行扩展,它的主体可以访问类的成员、覆盖它的方法等等,这和其他任何标准的类都是一样的。如果匿名类实现了一个接口,它的主体必须实现接口的方法。
注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。
在使用匿名内部类时,要记住以下几个原则:
1、匿名内部类不能有构造方法。
2、匿名内部类不能定义任何静态成员、方法和类。
3、匿名内部类不能是public,protected,private,static。
4、只能创建匿名内部类的一个实例。
5、一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
6、因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。内部类只能访问外部类的静态变量或静态方法。
匿名类和内部类中的中的this :有时候,我们会用到一些内部类和匿名类。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。
本文出自 “中场的艺术大师” 博客,请务必保留此出处http://linkinhardwork.blog.51cto.com/2694130/1140452
静态内部类:
静态内部类有两个特点:
1. 静态内部类使用static修饰,声明在类体中
2. 静态内部类可以访问外部累的静态成员(就好像静态方法可以访问静态变量一样)
看代码:
public class StatClas { public static int w=9; static class Test{ private int i=9; public static int j=8; public int get(){ System.out.println("内部类的J是"+j); return i; } public static int get0(){ System.out.println("外部类W的值是"+w); return j; } } public static void main(String args[]){ /***可以通过调用静态方法的办法调用静态内部类,然后调用其静态方法**/ StatClas.Test.get0(); /*** * 静态内部类: * StatClas相当于Test类的包,为Test声明一个命名空间 * 静态内部类的作用域,类似于静态变量,类加载以后就存在 * 可以在静态内部类中访问静态成员和静态方法。 * 静态内部类的好处是:将内部类封装入外部类,为内部类声明一个命名空间 * * */ //直接在本包中声明内部类的对象 Test t= new Test(); //通过对象调用内部类的成员方法 t.get(); //通过外部类名.内部类 声明对象 StatClas.Test t0= new StatClas.Test(); t0.get(); } }
成员内部类
成员内部类有两个特点:
1. 声明在类体中,不使用static,具有类的成员特征,也就是,必须使用外部类的实例才能创建内部类实例
2. 内部类实例可以访问外部类的成员变量
看代码:
public class InClass { private int i=9; public String name= "inclass"; public static String name0="test"; public class Test{ private String name="test"; public int j=9; public void get(){ System.out.println("name的值"+name+" "+"i的值"+i+" "+"name0的值"+name0); } } public static void main(String args[]){ //不可以像静态内部类的声明一样声明Test对象 //Test t= new Test(); //声明内部类对象的方式,也不可以,因为内部类是成员内部类,需要有外部类的实例 //Test t= new InClass.Test(); /**** * 成员内部类是外部类的成员,是依据于外部类对象而存在的,所以声明内部类对象的时候要通过外部累对象来声明 * ***/ InClass ic= new InClass(); Test t= ic.new Test(); t.get(); System.out.println(t.getClass()); /**输出为 * name的值test i的值9 name0的值test * class com.innnerclass.zhuxuli.InClass$Test * * */ } }
局部内部类
把类声明在方法中,就是局部内部类,作用域类似局部变量
看代码
public class LoClass { private final int i=9; private int d=3; private final String name="loclass"; public void testClass(){ int j=10; //int d=5; final int w=2; final String name="testclass"; class Test{ /*** * 局部内部类访问的方法中的局部变量必须为final类型 * 然而,局部变量可以访问成员变量,成员变量无须final定义 * 成员变量中的声明的变量被方法中重新声明为局部变量,如果需要在局部内部类中访问,必须定义为final类型 * ***/ public int get(){ return w+name.length(); } public int get0(){ return i+w; } public int get1(){ return d+w; } } Test t= new Test(); System.out.println("get方法"+t.get()+"\r\n get0方法"+t.get0()+"\r\n get1方法"+t.get1()); } public static void main(String args[]){ LoClass lc= new LoClass(); lc.testClass(); /** * 输出结果是: * get方法11 * get0方法11 * get1方法5 * ***/ } }
匿名内部类
在长篇幅的说明匿名内部类这个非常重要的概念前,我们先用简单的话说明什么是匿名内部类。
举例子
public class NimClass { private int w=9; private final int z=10; private static int x=4; public static void main(String args[]){ int i=5; final int j=8; final String name="测试匿名内部类"; Test t= new Test(){ int get(){ System.out.println("匿名内部类实现了Test"); /** * 1、虽然局部内部类的所有规则适用于匿名内部类 * 但是匿名内部类不能访问外部类的成员变量和成员函数,但是可以访问方法中的final变量 * 2、匿名内部类是实现的某一个抽象类或者接口,所以他不能定义任何静态方法,成员方法 * 匿名内部类不能是public,protected,private,static * 3、匿名内部类只能访问外部累的静态变量和静态方法 * * ***/ System.out.println(j+x); return 1; } }; Test0 t0= new Test0(){ public int get(){ System.out.println(); return 2; } }; } } abstract class Test{ abstract int get(); } interface Test0{ int get(); }
匿名类是不能有名称的类,所以没有办法引用他们。必须在创建时,作为new语句的一部分类声明匿名类,这就要采用另一种形式的new语句,如下所示: new <类或接口> <类的主体> 这种形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口。它还创建那个类的一个新实例,并把它作为语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数,后跟匿名类的主体。如果匿名类对另一个类进行扩展,它的主体可以访问类的成员、覆盖它的方法等等,这和其他任何标准的类都是一样的。如果匿名类实现了一个接口,它的主体必须实现接口的方法。
注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。
在使用匿名内部类时,要记住以下几个原则:
1、匿名内部类不能有构造方法。
2、匿名内部类不能定义任何静态成员、方法和类。
3、匿名内部类不能是public,protected,private,static。
4、只能创建匿名内部类的一个实例。
5、一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
6、因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。内部类只能访问外部类的静态变量或静态方法。
匿名类和内部类中的中的this :有时候,我们会用到一些内部类和匿名类。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。
本文出自 “中场的艺术大师” 博客,请务必保留此出处http://linkinhardwork.blog.51cto.com/2694130/1140452