内部类分为一下几种
普通内部类 静态内部类 局部内部类 匿名内部类
下面将一一进行介绍总结 普通内部类 public class Outer { //外部类 private int a = 10; private int b = 30; public class Inner{ //普通内部类 private int b = 20; //与外部类同名的成员变量 public void test(){ System.out.println(“访问外部成员变量”+a); System.out.println(“默认访问内部成员”+b); System.out.println(“访问内部成员”+this.b); System.out.println(“这样访问外部成员”+Outer.this.b); } } public static void main(String[] args) { Outer o = new Outer(); //创建外部类对象 Inner inner = o.new Inner(); //创建内部类对象 inner.test(); } } 123456789101112131415161718 注意:
内部类中可以直接访问外部类的属性,并且不受访问修饰符的限制 创建内部类对象时必须使用必须使用:内部类 对象名 = 外部类对象.new 内部类( );
静态内部类 public class SOuter { //外部类 private static String a = “外部类静态成员”; private String b = “外部类非静态成员”;
public static class SInner{ //静态内部类 private static String a = “内部类静态成员”;
public void test(){ System.out.println(SOuter.a); //打印:外部类静态成员 System.out.println(a); //打印:内部类静态成员 System.out.println(new SOuter().b); //打印:外部类非静态成员 } }
public static void main(String[] args) { SInner sInner = new SInner(); //创建静态内部类对象 sInner.test(); } } 12345678910111213141516171819 注意
静态内部类不能直接访问外部类的非静态成员,要用new 外部内().成员 的方式来访问 如果外部类的静态成员名称与内部类的静态成员名称不相同,则可直接使用成员名来访问,如果名称相同,则使用外部类.成员名来访问外部成员 创建内部类时不需要内部类对象,可直接使用new关键字获得
局部内部类 public class MOuter { public void test(){ int a = 10; //变量 final int b = 20; //常量 class MInner{ int c = 30; public void show(){ System.out.println(“访问外部常量:”+b); System.out.println(“访外部变量:”+a); System.out.println(“访问内部变量:”+c); } } MInner mInner = new MInner(); mInner.show(); }
public static void main(String[] args) { MOuter mOuter = new MOuter(); mOuter.test(); } } 123456789101112131415161718192021 注意:
作用域仅在代码块中 由于不能被代码块外部访问,所以局部内不能增加static关键字和访问权限修饰
匿名内部类 public class Anonymity { public static void main(String[] args) { //匿名内部类继承抽象类 Person person = new Person() { @Override void run() { System.out.println(“跑步,锻炼身体…”); } }; person.run(); //调用方法 //匿名内部类实现接口 IFly fly = new IFly() { @Override public void fly() { System.out.println(“起飞…”); } }; fly.fly(); //调用方法 } } abstract class Person{ abstract void run(); } interface IFly{ void fly(); } 1234567891011121314151617181920212223242526 注意:
同时只能继承一个类或实现一个接口,两者不可兼得 匿名内部类中是不能定义构造函数的 匿名内部类中不能存在任何静态变量和静态方法 匿名内部类为局部内部类,所以局部内部类的限制对匿名内部类同样生效 匿名内部类不能抽象的他必须实现继承的类,或实现接口中的方法
重点难点:
当内部类所在方法的形参被匿名内部类里面使用到时,必须把方法的形参使用final关键字声明
public class Anonymity { public static void main(String[] args) { test(“ADC”); }
private static void test(final String name){ IFly fly = new IFly() { @Override public void fly() { System.out.println(name+“起飞了”); } }; fly.fly(); } } 123456789101112131415 原因是:内部类并不直接调用方法传递的参数,而是利用自身的构造器来对传入的参数进行备份,自己内部的调用实际上是自己的属性,而不是方法传入的参数,test()函数传入的name参数与内部类中调用name属性看上去是同一个东西,但是实际上却不是,两者可以任意改变,不会相互影响,这在程序员的角度看来是不可行的,应为怎么看两则都像是同一个东西 所以结论就是必须加入final关键词来修饰在内部类中用到的外部函数传入的形参保持参数的一致性
可以使用构造块来完成初始化匿名内部类的工作,相当于构造器的效果
public class OutClass { private IFly getIFlyClass(final String _type,final int _age){ return new IFly() { int age; String type; { //使用构造块来进行初始化 if(_age >0 && _age < 500){ age = _age; type= _type; } } @Override public void fly() { System.out.println(type+“进行飞行…”+“年龄:”+age); } }; }
public static void main(String[] args) { IFly fly = new OutClass().getIFlyClass(“flying man”, 410); fly.fly(); } }
interface IFly{ //飞行接口 void fly(); }
------程序输出: flying man进行飞行…年龄:410