(一)简单内部类(直接定义在外部类的域中)
简单内部类相当于外部类的一个普通成员,因此内部类可以访问到外部类的所有成员(包括private成员)
而外部类一旦有一个内部类的对象,就可以访问该对象的所有成员(包括private成员)
需要注意的是如果只是定义了内部类,那么在外部类中是没有该内部类的对象实例的,需要在外部类中声明该内部类对象然后将其初始化
public class A{ ... public class InnerA{ ... } ... }
1.内部类访问外部类
内部类可访问外部类所有成员
public class A{ //外部类成员 private int a1=1; private static int a2=1; //外部类方法 private int getA1(){return a1;} private static int getA2(){return a2;} public class InnerA{ //内部类可访问外部类所有成员 private int ia=a1+a2+getA1()+getA2()+A.getA2(); } }
可以直接使用外部类成员名来访问
private int ia=a1+a2+getA1()+getA2()+A.getA2();
但严谨一点可使用外部类引用(OuterClass.this)来访问
private int ia=A.this.a1+A.this.a2+A.this.getA1()+A.this.getA2();
2.外部类访问内部类
外部类也可以访问到内部类的所有成员(包括private),但必须通过内部类对象来访问
//外部类访问内部类 public int getInnerAia(){ //获得内部类对象 InnerA innerA=new InnerA(); return innerA.ia; }
3.内部类访问另一内部类
内部类之间也可以相互访问私有成员,但是必须要有实体对象才能访问
public class InnerA{ private int ia=A.this.a1+A.this.a2+A.this.getA1()+A.this.getA2(); private int getIa(){return ia;} } private class InnerB{ //错误访问 //private int ib=ia //正确访问,实例对象 private int ib=new InnerA().ia; }
4.其他类访问内部类
把内部类看成一个外部类的成员,那么其他类就只能访问到public的内部类(同一包下default和proteced也可以)
public class A{ ... public class InnerA{ private int ia=A.this.a1+A.this.a2+A.this.getA1()+A.this.getA2(); public int getIa(){return ia;} } private class InnerB{ ... } } class otherClass{ public void getAInnerClass(){ A aClass=new A(); A.InnerA aInnnerClass=aClass.new InnerA();
aInnerClass.getIa();
//不能访问到private的InnerB
}
}
5.嵌套内部类
public class A{ ... public class InnerA{ private int ia=A.this.a1+A.this.a2+A.this.getA1()+A.this.getA2(); public int getIa(){return ia;} //嵌套内部类 public class InnerC{ private int ic=ia; } }
嵌套内部类InnerC相当于InnerA的成员,因此它只能访问InnerA的所有成员,而不能访问到A
(二)局部内部类
当只需要使用一次时,在一个方法中定义的内部类,不能有public或private修饰,作用域被限制在这个局部类的块中,因此外部类的其他成员也无法访问它,但是它却可以访问除了该方法外的其他外部成员
public void testMethodInnerClass(){ int methodId=1; class c{ int getMethodId(){ return methodId+a1; } } }
(三)匿名内部类
当只需创建一个类的对象就不需要命名的类
构造函数的小括号后跟的一个大括号,里面定义的就是匿名内部类
public static void main(String[] argv){ A a=new A() { int myA=10086; int getMyA(){return myA;} }; //双括号初始化,创建一个只是用一次的匿名arrayList //第一个括号说明是匿名内部类,第二个括号是初始化块:嗲用ArrayList的add方法添加元素 new ArrayList<String>(){{add("1");add("2");}}; }
(四)静态内部类
当内部类不需要引用外部类的成员时,可设为static
最景帝啊的运用是用作对象返回多个值,此例子遍历一次数组可返回最大最小值,就是通过内部类对象存储两个值然后返回实现
/** * @ClassName Arraylg * @Description TODO * @Author cherry * @Date 2018/6/11 11:23 * @Update 2018/6/11 11:23 **/ public class Arraylg{ /** * 用于存放两个double值,当外部类方法需要返回两个值时返回它即可 */ public static class Pair{ private double first; private double second; public Pair(double f,double s){ this.first=f; this.second=s; } public double getFirst(){ return first; } public double getSecond(){ return second; } } /** * 返回Pair可以求得double数组的最大最小值 * @param values * @return */ public static Pair minmax(double[] values){ double min=Double.POSITIVE_INFINITY; double max=Double.NEGATIVE_INFINITY; for(double v:values){ if(min>v)min=v; if(max<v)max=v; } return new Pair(min,max); } } class Test{ public static void main(String[] argv){ Arraylg.Pair pair=Arraylg.minmax(new double[]{5.0,10.0,1.0,4.5,9.1}); System.out.println("max:"+pair.getSecond()); System.out.println("min:"+pair.getFirst()); } }
注意事项
- 内部类不允许有static方法和static数据域
- 所有类只有内部类可以是private的