内部类是指在一个外部类的内部再定义一个类。
①内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
②内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
③内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量。(这与类中的静态成员方法只能访问静态成员是类似的)
①内部类可以很好的实现隐藏,一般的非内部类,是不允许有private和protected访问权限,但内部类可以。
②内部类拥有外围类的所有元素的访问权限。
③可是实现多重继承。
④可以避免修改接口而实现同一个类中两种同名方法的调用。
java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。
成员内部类,直接定义在类中。就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。同时外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
要注意的是,成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。
成员内部类可用访问权限修饰符public,protected,friendly(默认),private。
class Outer { public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); //创建成员内部类的对象,左边的Outer可以不要 inner.print("调用内部类的方法"); } public class Inner { public void print(String str) { System.out.println(str); } } }
局部内部类,是指内部类定义在方法和作用域内。
局部内部类只在该方法或条件的作用域内才能使用,退出这些作用域后无法引用的。
局部内部类可用访问权限修饰符只有friendly(默认)。
定义在方法内:
class Outer { public In play(){ class Inner extends In{ public void print(String str) { System.out.println(str); } } return new Inner(); } public static void main(String[] args) { Outer outer = new Outer(); In inner = outer.play(); //创建指向局部内部类的基类对象引用,只有这样才可以在局部内部类的作用于外使用局部内部类 inner.print("调用内部类的方法"); } } class In{ public void print(String str) { } }定义在作用域里:
class Outer { public In play(int i){ if(i>5){ class Inner extends In{ public void print(String str) { System.out.println(str); } } return new Inner(); } return null; } public static void main(String[] args) { Outer outer = new Outer(); In inner = outer.play(2014); //创建指向局部内部类的基类对象引用,只有这样才可以在局部内部类的作用于外使用局部内部类 inner.print("调用内部类的方法"); } } class In{ public void print(String str) { } }
与成员内部类定义的唯一区别是前面加了一个static的修饰符。
静态内部类,不需要内部类对象和外部类对象之间的联系。
静态内部类和成员的内部类还有两个个区别:
①成员内部类不能有static数据和static属性,也不能包含静态内部类,但静态内部类可以。
②创建内部类对象时静态内部类必须用Outer.Inner,成员内部类可以用Outer.Inner,也可以用Inner。
class Outer { static class Inner{ static class In{ } public void print(String str) { System.out.println(str); } } public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); //创建静态内部类的对象 inner.print("调用内部类的方法"); } }
有时候我为了免去给内部类命名,便倾向于使用匿名内部类,因为它没有名字。
匿名内部类是不能加访问修饰符的。即它的访问权限修饰符只能是friendly(默认的)。
要注意的是,new 匿名内部类,这个类是要先定义的。
匿名内部类实际上就是继承一个已经存在的类,但是省略自身类的名字。
当所在的方法的形参需要被内部类里面使用时,该形参必须为final。
class Outer { public Inner getInner(final int i,int j) { return new Inner(){ int k; { k=i;//如果是k=j,会报错 } }; } public static void main(String[] args) { Outer outer = new Outer(); Inner inner = outer.getInner(2014,11); //创建指向匿名内部类的父类对象引用 } public class Inner { public void print(String str) { System.out.println(str); } } }